以 table 名称作为参数的动态 SQL
Dynamic SQL with table name as a parameter
我正在尝试执行一个过程,我将 table 名称和 2 个列名称作为参数发送到其中:
EXECUTE IMMEDIATE 'select avg(@column1) from @Table1 where REF_D = @column2' into ATTR_AVG;
我试过在 '@'
、':'
、'||'
的组合中使用变量,但似乎没有任何效果。
有没有人用过table名字作为参数。这里有一些解决方案,但 SQL 服务器
您只能将绑定变量(用冒号表示)用于值,而不能用于结构的一部分。您必须将 table 和列名连接到查询中:
EXECUTE IMMEDIATE 'select avg(' || column1 | ') from ' || Table1
|| ' where REF_D = ' || column2 into ATTR_AVG;
这意味着 REF_D
是一个固定的列名称,可以出现在任何 table 中,您将为此调用它;在上一个问题中,这似乎是一个变量。如果它实际上是一个字符串变量,那么您需要绑定并设置它:
EXECUTE IMMEDIATE 'select avg(' || column1 | ') from ' || Table1
|| ' where ' || column2 || ' = :REF_D' into ATTR_AVG using REF_D;
如果它应该是一个日期,你应该确保局部变量是正确的类型,或者明确地转换它。
您需要使用 ||
构造可执行语句(或者将其定义为一个包含占位符的字符串,然后您可以使用 replace
对其进行操作)。类似于:
create or replace procedure demo
( p_table user_tab_columns.table_name%type
, p_column1 user_tab_columns.column_name%type
, p_column2 user_tab_columns.column_name%type )
is
attr_avg number;
begin
execute immediate
'select avg(' || p_column1 || ') from ' || p_table ||
' where ref_d = ' || p_column2
into attr_avg;
dbms_output.put_line('Result: ' || attr_avg);
end demo;
通常最好先在调试器友好的变量中构建字符串,例如:
create or replace procedure demo
( p_table user_tab_columns.table_name%type
, p_column1 user_tab_columns.column_name%type
, p_column2 user_tab_columns.column_name%type )
is
attr_avg number;
sql_statement varchar2(100);
begin
sql_statement :=
'select avg(' || p_column1 || ') from ' || p_table ||
' where ref_d = ' || p_column2;
execute immediate sql_statement into attr_avg;
dbms_output.put_line('Result: ' || attr_avg);
end demo;
根据 ref_d
是什么,您可能需要小心比较它,因此以上内容可能需要更多工作,但希望它能给您一些想法。
编辑:但是请参阅 Alex Poole 的回答以获取有关使用绑定变量的注释。如果 ref_d
是一个变量,可能需要变成:
sql_statement :=
'select avg(' || p_column1 || ') from ' || p_table ||
' where ' || p_column2 || ' = :b1';
execute immediate sql_statement into attr_avg using ref_d;
(惯例是将搜索表达式放在右边,例如 where name = 'SMITH'
而不是 where 'SMITH' = name
,尽管它们与 SQL 是一样的。)
我正在尝试执行一个过程,我将 table 名称和 2 个列名称作为参数发送到其中:
EXECUTE IMMEDIATE 'select avg(@column1) from @Table1 where REF_D = @column2' into ATTR_AVG;
我试过在 '@'
、':'
、'||'
的组合中使用变量,但似乎没有任何效果。
有没有人用过table名字作为参数。这里有一些解决方案,但 SQL 服务器
您只能将绑定变量(用冒号表示)用于值,而不能用于结构的一部分。您必须将 table 和列名连接到查询中:
EXECUTE IMMEDIATE 'select avg(' || column1 | ') from ' || Table1
|| ' where REF_D = ' || column2 into ATTR_AVG;
这意味着 REF_D
是一个固定的列名称,可以出现在任何 table 中,您将为此调用它;在上一个问题中,这似乎是一个变量。如果它实际上是一个字符串变量,那么您需要绑定并设置它:
EXECUTE IMMEDIATE 'select avg(' || column1 | ') from ' || Table1
|| ' where ' || column2 || ' = :REF_D' into ATTR_AVG using REF_D;
如果它应该是一个日期,你应该确保局部变量是正确的类型,或者明确地转换它。
您需要使用 ||
构造可执行语句(或者将其定义为一个包含占位符的字符串,然后您可以使用 replace
对其进行操作)。类似于:
create or replace procedure demo
( p_table user_tab_columns.table_name%type
, p_column1 user_tab_columns.column_name%type
, p_column2 user_tab_columns.column_name%type )
is
attr_avg number;
begin
execute immediate
'select avg(' || p_column1 || ') from ' || p_table ||
' where ref_d = ' || p_column2
into attr_avg;
dbms_output.put_line('Result: ' || attr_avg);
end demo;
通常最好先在调试器友好的变量中构建字符串,例如:
create or replace procedure demo
( p_table user_tab_columns.table_name%type
, p_column1 user_tab_columns.column_name%type
, p_column2 user_tab_columns.column_name%type )
is
attr_avg number;
sql_statement varchar2(100);
begin
sql_statement :=
'select avg(' || p_column1 || ') from ' || p_table ||
' where ref_d = ' || p_column2;
execute immediate sql_statement into attr_avg;
dbms_output.put_line('Result: ' || attr_avg);
end demo;
根据 ref_d
是什么,您可能需要小心比较它,因此以上内容可能需要更多工作,但希望它能给您一些想法。
编辑:但是请参阅 Alex Poole 的回答以获取有关使用绑定变量的注释。如果 ref_d
是一个变量,可能需要变成:
sql_statement :=
'select avg(' || p_column1 || ') from ' || p_table ||
' where ' || p_column2 || ' = :b1';
execute immediate sql_statement into attr_avg using ref_d;
(惯例是将搜索表达式放在右边,例如 where name = 'SMITH'
而不是 where 'SMITH' = name
,尽管它们与 SQL 是一样的。)