ORA-00904 PL/SQL 中的标识符无效
ORA-00904 invalid identifier in PL/SQL
CREATE OR REPLACE PROCEDURE PURGE_PROGRAM
AS
BEGIN
DECLARE
v_param VARCHAR2(3500);
v_sql VARCHAR2(500);
v_purge_count NUMBER(17);
BEGIN
SELECT param INTO v_param FROM PARAMETERS WHERE NAME='rententionPeriod';
dbms_output.put_line('Param: '||v_param);
IF v_param IS NOT NULL THEN
SELECT COUNT(*) INTO v_purge_count
FROM
(
SELECT * FROM tbl1 WHERE TRUNC(SYSDATE) - TRUNC(UPDATE_DATE) > v_param
UNION ALL
SELECT * FROM tbl2 WHERE TRUNC(SYSDATE) - TRUNC(UPDATE_DATE) > v_param
)x;
v_sql := 'INSERT INTO tbl1_arc
SELECT * FROM tbl1 WHERE TRUNC(SYSDATE) - TRUNC(UPDATE_DATE) > v_param';
EXECUTE IMMEDIATE v_sql;
v_sql := 'INSERT INTO tbl2_arc
SELECT * FROM tbl2 WHERE TRUNC(SYSDATE) - TRUNC(UPDATE_DATE) > v_param';
EXECUTE IMMEDIATE v_sql;
END IF;
END;
END PURGE_PROGRAM;
/
以上过程,v_param 能够输出正确的值,但是随后我得到异常 ORA-00904: "V_PARAM": invalid identifier
也许 v_param 无法从字符串 v_sql 访问?
It must be the later code when i refer v_param in a SQL string that need to be execute
是的。 v_param
超出了您正在执行的动态 SQL 的范围。
您需要在动态 SQL 中使用绑定变量,并将值传递到:
v_sql := 'INSERT INTO tbl1_arc
SELECT * FROM tbl1 WHERE TRUNC(SYSDATE) - TRUNC(UPDATE_DATE) > :v_param';
EXECUTE IMMEDIATE v_sql USING v_param;
不直接相关,但最好避免在比较之前修改 table 列值;所以你可以这样做:
WHERE UPDATE_DATE > TRUNC(SYSDATE) - v_param
或者可能取决于您如何处理截止值 - 因此请检查返回了哪些值以及您实际想要的值:
WHERE UPDATE_DATE >= TRUNC(SYSDATE) + 1 - v_param
这将允许使用 UPDATE_DATE
上的索引,并且即使没有索引也能减少总体工作量。
CREATE OR REPLACE PROCEDURE PURGE_PROGRAM
AS
BEGIN
DECLARE
v_param VARCHAR2(3500);
v_sql VARCHAR2(500);
v_purge_count NUMBER(17);
BEGIN
SELECT param INTO v_param FROM PARAMETERS WHERE NAME='rententionPeriod';
dbms_output.put_line('Param: '||v_param);
IF v_param IS NOT NULL THEN
SELECT COUNT(*) INTO v_purge_count
FROM
(
SELECT * FROM tbl1 WHERE TRUNC(SYSDATE) - TRUNC(UPDATE_DATE) > v_param
UNION ALL
SELECT * FROM tbl2 WHERE TRUNC(SYSDATE) - TRUNC(UPDATE_DATE) > v_param
)x;
v_sql := 'INSERT INTO tbl1_arc
SELECT * FROM tbl1 WHERE TRUNC(SYSDATE) - TRUNC(UPDATE_DATE) > v_param';
EXECUTE IMMEDIATE v_sql;
v_sql := 'INSERT INTO tbl2_arc
SELECT * FROM tbl2 WHERE TRUNC(SYSDATE) - TRUNC(UPDATE_DATE) > v_param';
EXECUTE IMMEDIATE v_sql;
END IF;
END;
END PURGE_PROGRAM;
/
以上过程,v_param 能够输出正确的值,但是随后我得到异常 ORA-00904: "V_PARAM": invalid identifier
也许 v_param 无法从字符串 v_sql 访问?
It must be the later code when i refer v_param in a SQL string that need to be execute
是的。 v_param
超出了您正在执行的动态 SQL 的范围。
您需要在动态 SQL 中使用绑定变量,并将值传递到:
v_sql := 'INSERT INTO tbl1_arc
SELECT * FROM tbl1 WHERE TRUNC(SYSDATE) - TRUNC(UPDATE_DATE) > :v_param';
EXECUTE IMMEDIATE v_sql USING v_param;
不直接相关,但最好避免在比较之前修改 table 列值;所以你可以这样做:
WHERE UPDATE_DATE > TRUNC(SYSDATE) - v_param
或者可能取决于您如何处理截止值 - 因此请检查返回了哪些值以及您实际想要的值:
WHERE UPDATE_DATE >= TRUNC(SYSDATE) + 1 - v_param
这将允许使用 UPDATE_DATE
上的索引,并且即使没有索引也能减少总体工作量。