plsql动态语句

本文介绍如何使用SQL动态生成技术与Oracle存储过程,实现复杂的数据查询和操作,包括动态构造SQL语句和存储过程封装。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

--   select * from std_mes_shipdata ; 
--set serveroutput on  ;
做一个保存,以后参考:
create or replace package xxoutput
as
    type mycrs is ref cursor ;
    procedure xxfnsoutput ( cur out mycrs ) ;
end ;

create or replace package body xxoutput
as
    procedure xxfnsoutput ( cur out mycrs )
    is
  
      tmpSQLString varchar2(4000) ;
      iLoopN number ;
      iLoopDayth number ;
      iDaythNow number ;     
     
    begin    
        iLoopN := 1 ;
        iLoopDayth :=1 ;
        iDaythNow := to_number( substr( to_char ( sysdate,'YYYYMMDD' ),7,2 ) ) ;
        tmpSQLString := ' select productSquare ' ;
        --  动态SQL :
        while iLoopDayth <= iDaythNow
        loop
            tmpSQLString := tmpSQLString || ', sum( decode ( dayn, '''||to_char(  trunc(sysdate,'MM')+(iLoopDayth-1),'YYYYMMDD' )
                                                                  ||''',qty,0)) as '||'D'
                                                                  ||to_char(  trunc(sysdate,'MM')+(iLoopDayth-1),'YYYYMMDD' ) ;
            iLoopDayth := iLoopDayth +1 ;
        end loop ;       
       
        --  附 动态SQL的源表:   
        tmpSQLString := tmpSQLString || ' from ( select case substr(trim(product_id),1,1)
                                                            when ''F'' then ''4''
                                                            when ''W'' then ''5''
                                                            when ''M'' then ''6''
                                                         end  as productSquare,         
                                                         substr(trim(ship_date),1,8) as dayn,
                                                         sum(qty) as qty
                                                  from   std_mes_shipdata 
                                                  where  substr(trim(ship_date),1,6) = substr( to_char( trunc( sysdate,''MM''),''YYYYMMDD''  ),1,6) 
                                                  group by substr(trim(product_id),1,1) ,  substr(trim(ship_date),1,8)
                                                  order by  substr(trim(ship_date),1,8)  ) drtbl group by productSquare '  ;
                         
      --  打印最后的SQL 语句:     
      /*
        while iLoopN<=length( trim( tmpSQLString )  )
        loop
              dbms_output.put_line( substr( trim( tmpSQLString ) ,iLoopN, 150 ) )  ;
              iLoopN := iLoopN +150 ;         
        end loop ;   
      */
      open cur for tmpSQLString ;
    end ;
end ;


PL/SQL 中的查询语句通常嵌套在程序块中,用于从数据库中检索数据。这些查询语句主要使用 `SELECT INTO` 语法,将结果存储到变量中,适用于单行查询场景。对于多行查询,需要结合游标(Cursor)进行处理。 ### 基本查询语句结构 PL/SQL 查询语句通常包含以下几个部分: 1. **声明变量**:定义变量以存储查询结果。 2. **执行查询**:使用 `SELECT INTO` 语法将查询结果赋值给变量。 3. **异常处理**:捕获可能发生的错误,例如没有找到数据或返回多行数据。 以下是一个基本的 PL/SQL 查询示例: ```plsql DECLARE emp_name employees.emp_name%TYPE; BEGIN SELECT emp_name INTO emp_name FROM employees WHERE emp_id = 100; DBMS_OUTPUT.PUT_LINE('Employee Name: ' || emp_name); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('No employee found with ID 100'); WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE('Multiple employees found with the same ID'); END; / ``` 上述代码通过 `SELECT INTO` 语句从 `employees` 表中查询 `emp_id = 100` 的员工姓名,并将其存储在 `emp_name` 变量中。如果找不到数据或返回多行数据,则分别触发 `NO_DATA_FOUND` 和 `TOO_MANY_ROWS` 异常 [^2]。 --- ### 使用游标进行多行查询 当查询语句返回多行数据时,必须使用 **显式游标** 或 **隐式游标 FOR 循环** 来处理每一行数据。以下是使用显式游标的示例: ```plsql DECLARE CURSOR emp_cursor IS SELECT emp_id, emp_name FROM employees WHERE department_id = 20; emp_record emp_cursor%ROWTYPE; BEGIN OPEN emp_cursor; LOOP FETCH emp_cursor INTO emp_record; EXIT WHEN emp_cursor%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Employee ID: ' || emp_record.emp_id || ', Name: ' || emp_record.emp_name); END LOOP; CLOSE emp_cursor; END; / ``` 该示例通过显式游标遍历部门编号为 20 的所有员工信息,并输出每条记录的内容 [^2]。 --- ### 使用 IF 语句控制查询逻辑 PL/SQL 还支持流控制语句,例如 `IF` 和 `LOOP`,可以根据特定条件动态调整查询逻辑。以下是一个结合 `IF` 判断的查询示例: ```plsql DECLARE score INTEGER := 85; attendance INTEGER := 80; result VARCHAR2(20); BEGIN IF score >= 60 AND attendance >= 75 THEN result := '通过'; ELSE result := '未通过'; END IF; DBMS_OUTPUT.PUT_LINE('考试结果: ' || result); END; / ``` 此代码通过 `IF` 语句判断学生的成绩和出勤率是否满足要求,并输出相应的考试结果 [^3]。 --- ### 优化 PL/SQL 查询性能 为了提高 PL/SQL 查询性能,可以采取以下措施: - **减少网络流量**:PL/SQL 以整个语句块发送到服务器,避免频繁的 SQL 单条传输,从而降低网络拥堵 [^1]。 - **使用绑定变量**:减少硬解析次数,提升执行效率。 - **索引优化**:确保查询字段有适当的索引支持,加快检索速度。 --- ### 总结 PL/SQL 查询语句的核心在于 `SELECT INTO` 结构与游标的配合使用,同时可以通过流控制语句实现复杂的业务逻辑。合理使用游标、变量和异常处理机制,可以编写高效且稳定的 PL/SQL 程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dbLenis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值