zoukankan      html  css  js  c++  java
  • orcle中如何使用动态游标来对变量进行赋值

    在oracle中动态游标的概念一般不常用,但有时根据客户的特殊业务,需要使用到动态游标来解决问题!在对于一条动态SQL语句而产生多条记录时,动态游标的使用将是一个很好的选择,具体参见如下在工作流项目中所应用到的用例:

    CREATE OR REPLACE PROCEDURE PRO_WF_IMPORT_FROMCTAIS
    AS
    LV_INSID       VARCHAR2(20);
    LV_IDEAID      VARCHAR2(20);
    LV_CREATOR    VARCHAR2(20);
    LV_OID       VARCHAR2(20);
    LV_BTID        VARCHAR2(20);
    LV_PAYER      VARCHAR(20);
    LI_RECORDCOUNT   NUMBER;
    LV_MESSAGE       VARCHAR2(20);
    LV_SQL           VARCHAR2(4000);
    LV_SQLSTATEMENT  VARCHAR2(4000);--动态SQL
    LV_EXIST         NUMBER;
    LI_SRCURSOR      INTEGER := DBMS_SQL.OPEN_CURSOR;--定义动态游标
    LI_SRNORE        INTEGER;--动态sql语句执行返回
    LI_DBLINK        VARCHAR2(20);
    
    CURSOR IMPORTWORKFLOW IS
    SELECT ID, SQLSTATEMENT, REPEATE
    FROM T_WF_ENG_INS_FROMCTAIS
    WHERE EXECUTE = '1';
    
    ERR_GET_IDEAID              EXCEPTION;
    ERR_GET_FROMCTAIS_INFO      EXCEPTION;
    BEGIN
    
       FOR V_IMPORTRECORD IN IMPORTWORKFLOW LOOP
          INSERT INTO T_WF_ENG_IMPORT_LOG(ID, SQLSTATEMENT, WFID, EXECUTETIME)
         VALUES(S_IMPROT_LOG.NEXTVAL, V_IMPORTRECORD.SQLSTATEMENT, V_IMPORTRECORD.ID, SYSDATE);
            COMMIT;
    
               LV_SQL := 'SELECT UPPER(SQLSTATEMENT) FROM T_WF_ENG_INS_FROMCTAIS '||
                  ' WHERE EXECUTE = ''1''' || ' AND ID=''' || V_IMPORTRECORD.ID ||'''';
               EXECUTE IMMEDIATE LV_SQL INTO LV_SQLSTATEMENT;;--得到动态SQL语句.
               SELECT DB_LINK INTO LI_DBLINK FROM USER_DB_LINKS;
               LV_SQLSTATEMENT :=  REPLACE(LV_SQLSTATEMENT,' WHERE','@'||LI_DBLINK||' WHERE');--替换成dblink方式.得到最终的动态SQL语句.
               LV_SQL := SUBSTR(LV_SQLSTATEMENT,INSTR(LV_SQLSTATEMENT,'FROM',1),LENGTH(LV_SQLSTATEMENT));
               LV_SQL := REPLACE(LV_SQL,'FROM','SELECT COUNT(*) FROM');--用于判断此动态语句是否有记录.
               EXECUTE IMMEDIATE LV_SQL INTO LV_EXIST;
               IF LV_EXIST <>0 THEN        --使用动态游标的开始
                 DBMS_SQL.parse(LI_SRCURSOR,LV_SQLSTATEMENT,DBMS_SQL.native);
                 DBMS_SQL.define_column(LI_SRCURSOR,1,LV_CREATOR,20);
                 DBMS_SQL.define_column(LI_SRCURSOR,2,LV_OID,20);
                 DBMS_SQL.define_column(LI_SRCURSOR,3,LV_BTID,20);
                 DBMS_SQL.define_column(LI_SRCURSOR,4,LV_PAYER,20);
                 LI_SRNORE := DBMS_SQL.execute(LI_SRCURSOR);
                 
                 LOOP
                  IF DBMS_SQL.FETCH_ROWS(LI_SRCURSOR) = 0 THEN
                       EXIT;
                  ELSE
                          DBMS_SQL.COLUMN_VALUE(LI_SRCURSOR, 1, LV_CREATOR);
                          DBMS_SQL.COLUMN_VALUE(LI_SRCURSOR, 2, LV_OID);
                          DBMS_SQL.COLUMN_VALUE(LI_SRCURSOR, 3, LV_BTID);
                          DBMS_SQL.COLUMN_VALUE(LI_SRCURSOR, 4, LV_PAYER);
                  END IF;
                  ---动态游标的结束(以end loop结束)
    
               IF LV_CREATOR IS NULL OR LV_OID IS NULL OR LV_BTID IS NULL OR LV_PAYER IS NULL THEN
                  RAISE ERR_GET_FROMCTAIS_INFO;
               END IF;
    
               IF V_IMPORTRECORD.REPEATE = '0' THEN
                  SELECT COUNT(B.INSID) INTO LI_RECORDCOUNT
                  FROM T_WF_ENG_INS_HSTY A, T_TAX_PRIVATE B
              WHERE A.CLASSID = V_IMPORTRECORD.ID AND A.ID = B.INSID AND B.PAYER = LV_PAYER;
                IF LI_RECORDCOUNT > 0 THEN
                     return;
                END IF;
             END IF;
    
            LV_INSID := FUN_WF_GET_MAX_INSID(LV_BTID);
            PRO_SYS_GET_MAXID('T_WF_ENG_IDEA_HSTY',LV_IDEAID, LV_MESSAGE);
    
               IF LENGTH(LV_MESSAGE) > 0 THEN
                  RAISE ERR_GET_IDEAID;
               END IF;
    
               SELECT COUNT(ID) INTO LV_EXIST FROM T_WF_ENG_INS_HSTY WHERE ID = LV_INSID;
               IF LV_EXIST=0 THEN
                  SELECT COUNT(MINSID) INTO LV_EXIST FROM T_WF_ENG_IDEA_HSTY WHERE MINSID = LV_INSID;
                  IF LV_EXIST=0 THEN
                   SELECT COUNT(INSID) INTO LV_EXIST FROM T_TAX_PRIVATE WHERE INSID = LV_INSID;
                     IF LV_EXIST=0 THEN
                    INSERT INTO T_WF_ENG_INS_HSTY(ID, CLASSID, CREATOR, OID, BTID, SDAY, EDAY, STATUS)
                    VALUES(LV_INSID, V_IMPORTRECORD.ID, LV_CREATOR, LV_OID, LV_BTID, SYSDATE, SYSDATE, 'C');
    
                    INSERT INTO T_WF_ENG_IDEA_HSTY(ID, MINSID, MACT, USERID, STARTTIME, ENDTIME)
                    VALUES(LV_IDEAID, LV_INSID, '1', LV_CREATOR, SYSDATE, SYSDATE);
    
                   INSERT INTO T_TAX_PRIVATE(INSID, PAYER) VALUES(LV_INSID, LV_PAYER);
                    COMMIT;
                     END IF;
                  END IF;
              END IF;
              END LOOP;            
             END IF;
       END LOOP;
        COMMIT;
        DBMS_SQL.CLOSE_CURSOR(LI_SRCURSOR);--最后关闭动态游标.
    
       EXCEPTION WHEN ERR_GET_IDEAID THEN
                       RAISE_APPLICATION_ERROR (-20001,LV_MESSAGE);
                  WHEN ERR_GET_FROMCTAIS_INFO THEN
                       RAISE_APPLICATION_ERROR (-20002,'对不起其它条件有为空的值!');
    END PRO_WF_IMPORT_FROMCTAIS;
  • 相关阅读:
    GNU make manual 翻译(九十九)
    GNU make manual 翻译( 九十五)
    Shell的 for 循环小例子
    makefile中对目录遍历的小例子
    GNU make manual 翻译(九十三)
    GNU make manual 翻译( 一百)
    GNU make manual 翻译( 九十七)
    GNU make manual 翻译( 九十八)
    mapserver4.8.3 的readme.win32的中文翻译文件
    遥控器编程
  • 原文地址:https://www.cnblogs.com/momoyan/p/9179993.html
Copyright © 2011-2022 走看看