db fiddle 现在不工作。稍后我会上传代码...
SELECT COUNT (*) FROM sys.odcivarchar2list ('2', '2');
Run Code Online (Sandbox Code Playgroud)
该查询无需使用关键字表即可工作。但在动态查询中:
DECLARE
c INTEGER;
towtimestwo SYS.odcivarchar2list := sys.odcivarchar2list ('2', '2');
BEGIN
EXECUTE IMMEDIATE 'SELECT COUNT (*) FROM :1'
INTO c
USING towtimestwo;
DBMS_OUTPUT.put_line (c);
END;
Run Code Online (Sandbox Code Playgroud)
它不起作用:
无效的表名
因此我必须添加关键字。
DECLARE
c INTEGER;
towtimestwo SYS.odcivarchar2list := sys.odcivarchar2list ('2', '2');
BEGIN
EXECUTE IMMEDIATE 'SELECT COUNT (*) FROM table( :1)'
INTO c
USING towtimestwo;
DBMS_OUTPUT.put_line (c);
END;
Run Code Online (Sandbox Code Playgroud)
为什么?
我正在使用 Oracle 19.0
因为当动态声明
'SELECT COUNT (*) FROM :1'
Run Code Online (Sandbox Code Playgroud)
被解析后,它会将 视为:1
表名,并且您不能将绑定变量用于表名或任何其他固定部分。您只能将绑定变量用于变量,即数据。
您传递的集合是否可以被视为表格并不重要;SQL 解析器还不知道(或关心)。
对于声明:
'SELECT COUNT (*) FROM table( :1)'
Run Code Online (Sandbox Code Playgroud)
现在它确实将 视为:1
变量,因为它周围有表表达式table()
,所以这是有效的。
您可以将原始静态 SQL 语句用作动态语句:
'SELECT COUNT (*) FROM sys.odcivarchar2list (''2'', ''2'')'
Run Code Online (Sandbox Code Playgroud)
或使用替代引用:
q'^SELECT COUNT (*) FROM sys.odcivarchar2list ('2', '2')^'
Run Code Online (Sandbox Code Playgroud)
因为它们也不会尝试使用绑定变量作为源表。