我可以在商店程序中查询游标时使用timestamp变量吗?

时间:2016-02-18 20:28:21

标签: sql oracle stored-procedures plsql

我需要一个时间戳变量,它可以改变dinamicaly,但是当我尝试将此timestamp变量传递给statement时,这不起作用:

没有时间戳变量,它可以工作:

CREATE OR REPLACE
PROCEDURE "PR_TEST"( sl_cursor OUT SYS_REFCURSOR)  
IS
    stm VARCHAR2(3000);
    var_ativo number:= 1 ;
BEGIN
    stm := 'SELECT
               *
        FROM
            SIMET.TB_1 SC
            JOIN SIMET.TB_2 D ON D.HASH = SC.HASH
        WHERE
             SC.IS_ACTIVE = ' || var_ativo ;            
     OPEN sl_cursor FOR  stm ;
END;

但是使用timestamp var,它不起作用:

CREATE OR REPLACE
PROCEDURE "PR_TEST"( sl_cursor OUT SYS_REFCURSOR)  
IS
    stm VARCHAR2(3000);
    var_ativo number:= 1 ;
    var_ts timestamp := SYSTIMESTAMP
BEGIN
    stm := 'SELECT
               *
        FROM
            SIMET.TB_1 SC
            JOIN SIMET.TB_2 D ON D.HASH = SC.HASH
        WHERE
             SC.IS_ACTIVE = ' || var_ativo 
         AND 
             sc.timestamp = ' || var_ts

     OPEN sl_cursor FOR  stm ;
END;

有人知道我该怎么做吗?

1 个答案:

答案 0 :(得分:1)

当前的问题是你没有正确地连接你的字符串;你需要将AND作为文字的一部分。你错过了一个分号。

stm := 'SELECT
           *
    FROM
        SIMET.TB_1 SC
        JOIN SIMET.TB_2 D ON D.HASH = SC.HASH
    WHERE
         SC.IS_ACTIVE = ' || var_ativo || '
     AND 
         sc.timestamp = ' || var_ts;

但现在您隐式将v_ts变量转换为字符串。作为字符串,它需要包含在转义的单引号中:

         sc.timestamp = ''' || var_ts || '''';

但是这涉及更多隐式转换以与列值进行比较,所以实际上你想要两种方式显式地转换它。正如你可能想象的那样,这是一个红旗,你做错了。

如果您使用的是动态SQL,则应使用绑定变量:

stm := 'SELECT
           *
    FROM
        SIMET.TB_1 SC
        JOIN SIMET.TB_2 D ON D.HASH = SC.HASH
    WHERE
         SC.IS_ACTIVE = :ativo
     AND 
         sc.timestamp = :ts';

 OPEN sl_cursor FOR stm USING var_ativo, var_ts;

但是从你所展示的内容来看,你根本不应该使用动态SQL:

 OPEN sl_cursor FOR
    SELECT
           *
    FROM
        SIMET.TB_1 SC
        JOIN SIMET.TB_2 D ON D.HASH = SC.HASH
    WHERE
         SC.IS_ACTIVE = var_ativo 
     AND 
         sc.timestamp = var_ts;

引用Tom Kyte:“You use dynamic sql only when there is quite simply NO WAY to do it statically.

您的前提是将您正在进行的操作拆分为较小的查询和更新可能不正确,并且您可能会使整体速度变慢;但这是一个单独的问题,需要更多信息才能解决。