You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PL/SQL存储过程优化:实现客户与车辆信息的非重复输出

PL/SQL存储过程优化:避免重复打印客户信息

刚接触PL/SQL,编写了customer_info存储过程,关联customer和car表查询指定customerid的客户与车辆信息。当前输出会重复打印客户姓名、地址、电话,希望仅打印一次客户基础信息,后续仅展示对应车辆的详细信息。

现有代码

create or replace procedure customer_info ( p_customerid customer.customerid%type)
as
cursor executive is
select  customername, address, phoneno, regno, carmodel, color, plateno
from customer c, car car
where c.customerid = p_customerid
and  c.customerid = car.customerid;

begin

for v_loop in executive loop

DBMS_OUTPUT.PUT_LINE ('Customer name:  ' || v_loop.customername);
dbms_output.put_line ('Customer Address:  ' || v_loop.address);
dbms_output.put_line ('Customer Phone Number:  ' || v_loop.phoneno);
dbms_output.put_line ('Car registiration number:  ' || v_loop.regno);
dbms_output.put_line ('Car model:  ' || v_loop.carmodel);
dbms_output.put_line ('Car color:  ' || v_loop.color);
dbms_output.put_line ('Car plate number:  ' || v_loop.plateno);
    end loop;
END customer_info;
/

当前输出

Customer name:  ahmed
Customer Address:  jeddah
Customer Phone Number:  538447169
Car registiration number:  car101
Car model:  mg5
Car color:  gray
Car plate number:  KSA 5808
Customer name:  ahmed
Customer Address:  jeddah
Customer Phone Number:  538447169
Car registiration number:  car113
Car model:  rio
Car color:  black
Car plate number:  ksa 5909

期望输出

Customer name:  ahmed
Customer Address:  jeddah
Customer Phone Number:  538447169
Car registiration number:  car101
Car model:  mg5
Car color:  gray
Car plate number:  KSA 5808
Car registiration number:  car113
Car model:  rio
Car color:  black
Car plate number:  ksa 5909

解决方案

方法一:基于原代码修改,添加标志变量控制打印

通过布尔变量标记是否已打印客户信息,仅在第一次循环时输出客户基础数据,后续循环只打印车辆信息:

create or replace procedure customer_info ( p_customerid customer.customerid%type)
as
cursor executive is
select  customername, address, phoneno, regno, carmodel, color, plateno
from customer c, car car
where c.customerid = p_customerid
and  c.customerid = car.customerid;
-- 定义标志变量,标记是否已打印客户信息
v_printed_cust boolean := false;
begin

for v_loop in executive loop
    -- 第一次循环时打印客户信息
    if not v_printed_cust then
        DBMS_OUTPUT.PUT_LINE ('Customer name:  ' || v_loop.customername);
        dbms_output.put_line ('Customer Address:  ' || v_loop.address);
        dbms_output.put_line ('Customer Phone Number:  ' || v_loop.phoneno);
        v_printed_cust := true;
    end if;
    -- 每次循环都打印车辆信息
    dbms_output.put_line ('Car registiration number:  ' || v_loop.regno);
    dbms_output.put_line ('Car model:  ' || v_loop.carmodel);
    dbms_output.put_line ('Car color:  ' || v_loop.color);
    dbms_output.put_line ('Car plate number:  ' || v_loop.plateno);
end loop;

-- 处理客户存在但无车辆的情况
if not v_printed_cust then
    declare
        v_cust_name customer.customername%type;
        v_cust_addr customer.address%type;
        v_cust_phone customer.phoneno%type;
    begin
        select customername, address, phoneno 
        into v_cust_name, v_cust_addr, v_cust_phone
        from customer where customerid = p_customerid;
        
        DBMS_OUTPUT.PUT_LINE ('Customer name:  ' || v_cust_name);
        dbms_output.put_line ('Customer Address:  ' || v_cust_addr);
        dbms_output.put_line ('Customer Phone Number:  ' || v_cust_phone);
        dbms_output.put_line ('No cars found for this customer.');
    exception
        when no_data_found then
            dbms_output.put_line ('Customer not found.');
    end;
end if;

END customer_info;
/

方法二:拆分查询,逻辑更清晰

分开查询客户信息和车辆信息,先打印客户数据,再循环打印该客户的所有车辆信息,避免关联查询的重复数据问题:

create or replace procedure customer_info ( p_customerid customer.customerid%type)
as
-- 客户信息游标
cursor c_customer is
select customername, address, phoneno
from customer where customerid = p_customerid;
-- 车辆信息游标,接收客户ID参数
cursor c_cars(p_custid customer.customerid%type) is
select regno, carmodel, color, plateno
from car where customerid = p_custid;
v_cust c_customer%rowtype;
begin
    -- 获取并打印客户信息
    open c_customer;
    fetch c_customer into v_cust;
    if c_customer%found then
        DBMS_OUTPUT.PUT_LINE ('Customer name:  ' || v_cust.customername);
        dbms_output.put_line ('Customer Address:  ' || v_cust.address);
        dbms_output.put_line ('Customer Phone Number:  ' || v_cust.phoneno);
        
        -- 遍历打印车辆信息
        for v_car in c_cars(p_customerid) loop
            dbms_output.put_line ('Car registiration number:  ' || v_car.regno);
            dbms_output.put_line ('Car model:  ' || v_car.carmodel);
            dbms_output.put_line ('Car color:  ' || v_car.color);
            dbms_output.put_line ('Car plate number:  ' || v_car.plateno);
        end loop;
        
        -- 无车辆时提示
        if c_cars%notfound then
            dbms_output.put_line ('No cars found for this customer.');
        end if;
    else
        dbms_output.put_line ('Customer not found.');
    end if;
    close c_customer;
END customer_info;
/

内容的提问来源于stack exchange,提问作者Ahmed AL-ghamdi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 01:40:38