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

有没有办法在调用中使用可变数量的绑定变量 EXECUTE IMMEDIATE 不知何故?

更具体地说,我需要通过 参数进入未知的SQL,但我不知道它在那里会被使用多久。

我尝试过类似的东西

EXECUTE IMMEDIATE 'SELECT SYSDATE FROM DUAL WHERE :var = :var' USING 1;

但它又回来了 ORA-01008: not all variables bound.

有帮助吗?

解决方案

您无法使用 EXECUTE IMMEDIATE 执行此操作。但是,您可以使用Oracle的 DBMS_SQL 包来完成此操作。 数据库应用程序开发人员指南包含您熟悉的 EXECUTE IMMEDIATE dbms_sql 方法之间的比较。 此页文档 DBMS_SQL ,但有一些例子(上面已链接)应该让你入门(例1是运行一个可能有任意数量绑定变量的语句的简单例子)。从编码的角度来看, DBMS_SQL 更加麻烦,但它可以让你做任何你能想到的事情。

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

其他提示

您还可以使用 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;

AskTom上的线程详细介绍了这个主题。

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

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

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

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

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

事实上,几天前我遇到了同样的问题,一位朋友与我分享了一种方法来做到这一点 EXECUTE IMMEDIATE.

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

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top