在 Oracle 10g 的 SQL 过程中使用游标的任何替代方法?

Posted

技术标签:

【中文标题】在 Oracle 10g 的 SQL 过程中使用游标的任何替代方法?【英文标题】:Any alternatives to using cursor in SQL procedure in Oracle 10g? 【发布时间】:2012-08-06 16:59:06 【问题描述】:

我为 SQL 提供了一些输入,我需要获取所有不满足所需条件的 ID 及其计数。

我想知道是否有任何替代使用光标的方法。

DECLARE
   v_count            INTEGER;
   v_output           VARCHAR2 (1000);
   pc                 table1%ROWTYPE;
   unmarked_ids       EXCEPTION;
   dynamic_sql        VARCHAR (5000);
   cur                SYS_REFCURSOR;
   id                 pp.id%TYPE;
   pos                INTEGER;
BEGIN
   v_count := 0;
   SELECT *
     INTO pc
     FROM table1
    WHERE id = '&ID';
   DBMS_OUTPUT.ENABLE;
      dynamic_sql :=
            'SELECT ID from pp
                    WHERE ( TO_CHAR(cdate, ''yyyy/mm/dd'') = 
                    TO_CHAR (:a, ''yyyy/mm/dd''))
                    AND aid IN (SELECT aid FROM ppd WHERE TO_CHAR(cdate, ''yyyy/mm/dd'') = 
                    TO_CHAR (:b, ''yyyy/mm/dd'')
                    AND cid = :c )
                    AND cid <> :d';
      OPEN cur FOR dynamic_sql USING pc.cdate, pc.cdate, pc.id, pc.id;
      LOOP
         FETCH cur INTO id;
         EXIT WHEN cur%NOTFOUND;
         v_count := v_count + 1;
         DBMS_OUTPUT.PUT_LINE (' Id:' || id);
      END LOOP;
      CLOSE cur;
   IF (v_count > 0)
   THEN
      DBMS_OUTPUT.PUT_LINE ( 'Count: ' || v_count || ' SQL: ' || dynamic_sql);
      RAISE unmarked_ids;
   END IF;
   DBMS_OUTPUT.PUT_LINE('SQL ended successfully');
EXCEPTION
   WHEN unmarked_ids
   THEN
      DBMS_OUTPUT.put_line (
         'Found ID's that not marked with the current id.');
   WHEN NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.put_line (
         'No data found in table1 with the current id ' || '&ID');
END;

查询中有绑定变量。其中一个是日期,还有三个。 需要显示计数和 ID,稍后会报告。

【问题讨论】:

为什么要使用动态SQL?在您发布的示例中,关于查询的任何内容都不是动态的,因此无需使用动态 SQL。您似乎在执行动态 SQL 而不使用绑定变量这一事实比您使用游标迭代结果这一事实更令人担忧。你真的在用你获取的ID 值做些什么吗?或者你只是在数他们? 实际上有一些绑定变量,比如日期和其他一些我在查询中没有提到的东西(我放了...)。如果 SQL 找到任何具有计数(ID 数)的 ID,稍后将报告这些 ID 那么,在实际代码中,date1 是作为绑定变量传入的,而不是像您的示例那样硬编码到 SQL 语句中?我不确定 ID 值“如果 SQL 发现任何计数后报告”意味着什么。你能详细解释一下吗? 是的,实际SQL中有绑定变量。这些 ID 将提供给 UC4 作业,如果找到任何 ID,该作业将失败。然后,PROD 支持团队将查看这些 ID 并解决问题。这些 ID 仅用于支持 PROD 支持团队。 好的,所以实际代码看起来与修改后的示例不同,实际上是在使用绑定变量?什么是“UC4 作业”?这段代码如何将它找到的 ID 值集提供给该作业? 【参考方案1】:

您可以将 rowid 与索引值 (0...n) 一起存储在临时表中,然后使用 while 循环遍历索引值并使用 rowid 连接到真实表。

【讨论】:

免责声明:我并不是说这是个好主意!这只是我见过的一种方法...... 我以前用过这种方法,它可以工作,比光标快,但带有一点健康警告

以上是关于在 Oracle 10g 的 SQL 过程中使用游标的任何替代方法?的主要内容,如果未能解决你的问题,请参考以下文章

使用 PL/SQL 过程在 oracle 10g 中转储表

如何从 Oracle 10G PL/SQL 函数和过程中查找所有表引用? [复制]

在 Oracle 10g 上使用“With”SQL 导致错误

Oracle 10g实现存储过程异步调用

oracle10g的存储过程大概怎么调试

oracle 10g中怎样执行很长的sql语句呢(最长可能有10万+字符)