2009-06-17 49 views
9

我需要在Oracle上使用动态SQL执行,我不知道运行时在SQL中使用的绑定变量的确切数量。带有可变绑定数量的Oracle EXECUTE IMMEDIATE可能吗?

有没有办法在EXECUTE IMMEDIATE调用中以某种方式使用可变数量的绑定变量?

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

我想是这样

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

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

+0

相关:为什么我不能使用绑定变量的动态SQL DDL/SCL语句? ](http://stackoverflow.com/q/25489002/1461424) – Krumia 2014-08-26 03:59:27

回答

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

2

Thread on AskTom涵盖细节主题掀开。

在你的情况,如果你想传递一个参数或没有,你可以建立一个只有一个参数,并在这些查询不使用它的一个(即谓词始终是真实的)两个查询是这样的:

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

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

您可能可以细化谓词,以便优化程序能够理解它始终为真。

+0

问题是传入的SELECT语句不知道,除了使用一个参数(ID)至少一次或甚至几次。绑定的数目是未知的。 – Kosi2801 2009-06-17 18:13:23

+0

如果参数个数未知,则必须使用dbms_sql – 2009-06-18 06:47:06

1

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

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

+0

它将在随后的PL/SQL中使用,因此客户端没有问题。 – Kosi2801 2009-06-18 07:49:02

4

您也可以通过使用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; 
1

更具体地说,我需要一个参数传递到未知的SQL,但我不知道多久它会在那里使用。

我居然遇到了这个完全相同的一个问题前几天,和一个朋友跟我分享的方式来完成这一功能与EXECUTE IMMEDIATE

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

看看我的例子/代码和我自己的类似问题/答案线程:

相关问题