Oracle EXECUTE IMMEDIATE可以使用可变数量的绑定吗?

时间:2009-06-17 15:45:04

标签: oracle plsql dynamic-sql

我需要在Oracle上使用动态SQL执行,我不知道运行前SQL中使用的绑定变量的确切数量。

有没有办法在某种程度上调用EXECUTE IMMEDIATE时使用可变数量的绑定变量?

更具体地说,我需要将一个参数传递给未知的SQL,但我不知道它在那里的使用频率。

我试过像

这样的东西
EXECUTE IMMEDIATE 'SELECT SYSDATE FROM DUAL WHERE :var = :var' USING 1;

但它以ORA-01008: not all variables bound.

退回

5 个答案:

答案 0 :(得分:9)

您无法使用EXECUTE IMMEDIATE执行此操作。但是,您可以使用Oracle的DBMS_SQL包来完成此操作。 Database Application Developer's Guide对您熟悉的EXECUTE IMMEDIATEdbms_sql方法进行了比较。 This page文档DBMS_SQL,但有一些示例(上面已链接)应该让您入门(示例1是运行可能具有任意数量的绑定变量的语句的简单情况)。从编码的角度来看,DBMS_SQL更加繁琐,但它可以让你做任何你能想到的事情。

允许在SQL中出现多个绑定变量实例。但是,您必须知道用作绑定变量的名称(例如:在您的情况下为var),以便将其传递给DBMS_SQL.BIND_VARIABLE

答案 1 :(得分:7)

您还可以使用WITH语句解决此问题。通常使用DBMS_SQL会更好,但有时这是一种更简单的方法:

BEGIN
    EXECUTE IMMEDIATE 'WITH var AS (SELECT :var FROM dual) SELECT SYSDATE FROM DUAL WHERE (SELECT * FROM var) = (SELECT * FROM var)' USING 1;
END;

答案 2 :(得分:2)

Thread on AskTom详细介绍了主题。

在您的情况下,如果您想传递一个参数或者没有传递,您可以构建两个具有单个参数的查询,并且在其中一个查询中不使用它(即谓词始终为true),如下所示:

-- query1
SELECT * FROM DUAL WHERE dummy = :x;

-- query2
SELECT * FROM DUAL WHERE nvl(:x, 1) IS NOT NULL;

您可以优化谓词,以便优化器能够理解它始终是真的。

答案 3 :(得分:1)

可以像Steve Broberg解释的那样使用dbms_sql,但是很多客户端无法使用(读取)生成的游标。 Oracle 11添加了一个转换函数(dbms_sql.to_refcursor),可以将dbms_sql游标转换为引用游标,但由于某种原因,不能在.Net应用程序中使用这个转换后的引用游标。可以在.net中使用正常的引用游标,但不能使用曾经是dbms_sql游标的引用游标。

那么什么样的客户端会消耗这个游标?

答案 4 :(得分:1)

  

更具体地说,我需要将一个参数传递给未知的SQL,但我不知道它将在那里使用的频率。

我实际上几天前碰到了同样的问题,而且有一位朋友与我分享了一种与EXECUTE IMMEDIATE完全相同的方法。

它涉及生成PLSQL块而不是SQL块本身。将EXECUTE IMMEDIATE与PLSQL代码块一起使用时,可以按名称绑定变量,而不是仅按位置绑定。

查看我的示例/代码以及我自己的类似问题/答案帖子: