我遇到了通过创建一系列插入语句为表创建备份的问题。
输入是表名,每个表可以有不同数量的列。假设数据类型可以是varchar2,数字或仅日期
所以我有这行代码:
execute immediate fetchStmt;
其中fetchStmt可以是:
fetch tableColCursor into valuesArray(1), valuesArray(2), ..., valuesArray(n)
这只是从游标中取出每一行并将其放入一个varray中,如果它不在execute immediate语句中,语句本身就可以工作。
我知道执行立即执行只能处理SQL查询或PL / SQL块。 问题是我如何能够完成这项工作或者是什么类似的问题解决方案呢?
请注意,在编译期间不知道表及其列及其数据类型
答案 0 :(得分:2)
EXECUTE IMMEDIATE
只能处理完整的语句,例如:SQL语句或PLSQL块(带[DECLARE]..BEGIN..END
)。
此外,以这种方式执行的块将不会看到来自调用块的任何变量(它们不共享相同的范围),例如这不起作用:
DECLARE
l NUMBER := 1;
k NUMBER := 0;
BEGIN
EXECUTE IMMEDIATE 'BEGIN l := k; END;';
END;
上述代码会产生错误,因为子块中未定义l
和k
。相反,您需要使用输入/输出变量:
DECLARE
l NUMBER := 1;
k NUMBER := 0;
BEGIN
EXECUTE IMMEDIATE 'BEGIN :P1 := :P2; END;' USING OUT l, k;
dbms_output.put_line(l); -- return 0
END;
在您的情况下,您不知道变量的数量,因此您将无法使用EXECUTE IMMEDIATE
。您可以使用DBMS_SQL
,但我认为有更简单的方法:您可以找到已经正常工作的代码(例如,它存在于Oracle APEX中),或者您可以通过运行可生成必要INSERT字符串的SELECT来自行编程。对于此方法,您必须动态生成SQL语句(取决于表列)。该语句看起来像这样(对于表TEST(a,b,c)
,其中所有列都是整数[需要适应其他数据类型]):
SELECT 'INSERT INTO test(a,b,c) VALUES ('||a||', '||b||', '||c||');'
FROM test