没有开始和结束的Oracle Native Dynamic SQL PL / SQL语句

时间:2012-11-16 08:23:14

标签: sql oracle plsql plsqldeveloper

我遇到了通过创建一系列插入语句为表创建备份的问题。

输入是表名,每个表可以有不同数量的列。假设数据类型可以是varchar2,数字或仅日期

所以我有这行代码:

execute immediate fetchStmt;

其中fetchStmt可以是:

fetch tableColCursor into valuesArray(1), valuesArray(2), ...,  valuesArray(n)

这只是从游标中取出每一行并将其放入一个varray中,如果它不在execute immediate语句中,语句本身就可以工作。

我知道执行立即执行只能处理SQL查询或PL / SQL块。 问题是我如何能够完成这项工作或者是什么类似的问题解决方案呢?

请注意,在编译期间不知道表及其列及其数据类型

1 个答案:

答案 0 :(得分:2)

EXECUTE IMMEDIATE只能处理完整的语句,例如:SQL语句或PLSQL块(带[DECLARE]..BEGIN..END)。

此外,以这种方式执行的块将不会看到来自调用块的任何变量(它们不共享相同的范围),例如这不起作用:

DECLARE
  l NUMBER := 1;
  k NUMBER := 0;
BEGIN
  EXECUTE IMMEDIATE 'BEGIN l := k; END;';
END;

上述代码会产生错误,因为子块中未定义lk。相反,您需要使用输入/输出变量:

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