我需要一个时间戳变量,它可以改变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;
有人知道我该怎么做吗?
答案 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.”
您的前提是将您正在进行的操作拆分为较小的查询和更新可能不正确,并且您可能会使整体速度变慢;但这是一个单独的问题,需要更多信息才能解决。