在oracle游标声明查询中使用变量

在oracle游标声明查询中使用变量,oracle,plsql,cursor,Oracle,Plsql,Cursor,有没有办法在游标声明sql中使用变量? 范例- 在这里,游标不会获取所需的记录。 我可以在游标声明之前的某个地方指定V_V1值吗? 虽然我可以在游标sql本身中获取日期,但是会有冗余的select查询。有更好的办法吗 继我的评论之后,也许这个工作示例确实给了您一个想法: DECLARE CURSOR c1(nId IN NUMBER) IS SELECT * FROM TableA

有没有办法在游标声明sql中使用变量? 范例-

在这里,游标不会获取所需的记录。 我可以在游标声明之前的某个地方指定V_V1值吗?
虽然我可以在游标sql本身中获取日期,但是会有冗余的select查询。有更好的办法吗

继我的评论之后,也许这个工作示例确实给了您一个想法:

DECLARE
        CURSOR c1(nId IN NUMBER) IS
               SELECT   * 
               FROM     TableA 
               WHERE    Id = nId;
BEGIN
        FOR r1 IN c1(nId => 3) LOOP
                --Do something here
                DBMS_OUTPUT.PUT_LINE('A');
        END LOOP;
END;
/

因此,在您的示例中,首先获取
V_V1
,然后使用该值打开光标

在循环光标之前,需要为V_V1赋值。此外,还需要在游标定义(游标c_dummy(V_V1 date))中定义变量,并在CUR_dummy(V_V1)中调用REC的游标时传递该变量


正如有人已经说过的,您需要将变量V_V1移出FOR循环。一旦光标被打开,结果集就被固定;因此,在循环中更改V_V1不会产生任何影响

下面的代码也避免了从dual中选择您不需要的变量(为了简单和性能,应该避免),并对变量进行了更有意义的命名(当我不知道代码的用途时,很难这样做-但我希望您在文章中对它们进行命名,并且在实际代码中它们与此不同)

同样,在不知道代码用途的情况下,请记住,BETWEEN是包含的,因此_date和_date+1之间的
可能包含您不想要的记录。我猜了一点,但是
=the_date和
可能是正确的子句

作为最佳实践建议,我还建议,如果您还没有将您的过程放入包中,那么您应该这样做,并且代码中的注释应该只用于解释为什么代码是这样的,而不是它是什么。i、 e.说明游标声明对代码可读性没有好处的注释。根据循环中的处理,您还应该考虑使用其他地方有详细记载的BooDebug。
CREATE OR REPLACE PROCEDURE my_procedure (in_var IN VARCHAR2)
IS    
   today_begin TABLE.DATE_COL%TYPE;
   the_day_begin TABLE2.DAY_BEGIN%TYPE;

   CURSOR todays_records( the_date DATE )
   IS
        SELECT COL1,COL2,COL3 
        FROM   TABLE 
        WHERE  DATE_COL BETWEEN the_date AND the_date + 1;

BEGIN

    SELECT DAY_BEGIN 
    INTO the_day_begin
    FROM TABLE2;

    today_begin := TO_DATE(TO_CHAR(sysdate, 'DD-MON-YY') ||' '|| TO_CHAR(the_day_begin,'HH24:MI:SS'),'DD-MON-YY HH24:MI:SS') 

    FOR rec IN todays_records( today_begin )
    LOOP
      --  other stuffs
    END LOOP;

END;

你们这些人不会工作的。因为在将值分配给
V_V1
之前,您已经执行了
选择
步骤。因此,在您的选择中,V_V1为空。感谢您的所有建议。是的,我为这篇文章重新命名了他们。
    create or replace PROCEDURE PRD (IN_VAR  IN VARCHAR2)
IS

  V_V1 TABLE.DATE_COL%TYPE;

   /* Cursor decleration */
   CURSOR CUR_DUMMY(V_V1 date)
   IS
        SELECT COL1,COL2,COL3 
          FROM TABLE 
             WHERE DATE_COL BETWEEN V_V1 
                    AND V_V1+1;

BEGIN
   SELECT TO_DATE(TO_CHAR(sysdate, 'DD-MON-YY') ||' '||(SELECT TO_CHAR(DAY_BEGIN,'HH24:MI:SS') FROM TABLE2),'DD-MON-YY HH24:MI:SS') INTO  V_V1 from DUAL;   
   FOR REC  IN CUR_DUMMY(V_V1)
   LOOP

--  do stuffs

    END LOOP;
END;
CREATE OR REPLACE PROCEDURE my_procedure (in_var IN VARCHAR2)
IS    
   today_begin TABLE.DATE_COL%TYPE;
   the_day_begin TABLE2.DAY_BEGIN%TYPE;

   CURSOR todays_records( the_date DATE )
   IS
        SELECT COL1,COL2,COL3 
        FROM   TABLE 
        WHERE  DATE_COL BETWEEN the_date AND the_date + 1;

BEGIN

    SELECT DAY_BEGIN 
    INTO the_day_begin
    FROM TABLE2;

    today_begin := TO_DATE(TO_CHAR(sysdate, 'DD-MON-YY') ||' '|| TO_CHAR(the_day_begin,'HH24:MI:SS'),'DD-MON-YY HH24:MI:SS') 

    FOR rec IN todays_records( today_begin )
    LOOP
      --  other stuffs
    END LOOP;

END;