oracle动态查询通过sql获取游标变量
Posted
技术标签:
【中文标题】oracle动态查询通过sql获取游标变量【英文标题】:oracle dynamic query fetch cursor variables through sql 【发布时间】:2014-07-08 15:24:30 【问题描述】:需要一点帮助。我有一个动态查询,将 4 个列名和两个表名输出到 6 个游标变量中。现在我需要使用游标变量来选择前 4 列,然后使用游标变量从两个表名中选择,因为这些包含数据认为使用包含查询但我不知道的变量通过查询获取的东西如何去做。这就是我现在所拥有的,我只需要获取游标变量并将它们放入查询中
DECLARE
arow VARCHAR2 (1000);
column1 VARCHAR2 (50);
column2 VARCHAR2 (50);
column3 VARCHAR2 (50);
column4 VARCHAR2 (50);
table1 VARCHAR2 (50);
table2 VARCHAR2 (50);
match VARCHAR2 (50);
match1 VARCHAR2 (50);
sql_statement VARCHAR2 (500);
BEGIN
FOR arow IN (SELECT column_name_old,
column_name_new,
column_name_old_2,
column_name_new_2,
table_name_old,
table_name_new
FROM A550003.META_DATA_TABLE)
LOOP
sql_statement :=
'INSERT'
|| ' '
|| 'INTO'
|| ' '
|| 'a550003.MATCH_TABLE'
|| ' '
|| 'SELECT '
|| arow.column_name_old
|| ', '
|| arow.column_name_new
|| ', '
|| 'DECODE( '
|| arow.column_name_old
|| ', '
|| arow.column_name_new
|| ','
|| '1'
|| ','
|| '0)'
|| 'AS'
|| ' '
|| 'MATCH'
|| ','
|| arow.column_name_old_2
|| ', '
|| arow.column_name_new_2
|| ','
|| 'DECODE( '
|| arow.column_name_old_2
|| ', '
|| arow.column_name_new_2
|| ','
|| '1'
|| ','
|| '0)'
|| 'AS'
|| ' '
|| 'MATCH1'
|| ' FROM '
||' '
|| arow.table_name_old
|| ', '
|| arow.table_name_new
|| ' WHERE '
|| arow.column_name_old
|| '='
|| arow.column_name_new
|| '(+)';
DBMS_OUTPUT.PUT_LINE (sql_statement);
EXECUTE IMMEDIATE sql_statement;
COMMIT;
END LOOP;
END;
【问题讨论】:
【参考方案1】:首先你的 sql_statement 是错误的。您应该将此变量的值设置为这样的(当您将获得所有需要的名称时):
sql_statement := 'SELECT '
|| column1
|| ', '
|| column2
|| ', '
|| column3
|| ', '
|| column4
|| ' FROM '
|| table1
|| ', '
|| table2
|| ' WHERE '
|| -- JOIN_CONDITION
然后你可以使用 EXECUTE IMMEDIATE 语句:
EXECUTE IMMEDIATE sql_statement
INTO col1_val
,col2_val
,col3_val
,col4_val
;
当然变量 col[1..4]_val 必须声明。
还要注意 SQL 注入。
【讨论】:
嘿 kpater 感谢您的回复,对不起,我没有大量使用动态 sql。我已经编辑了我原来的帖子查询,我不知道它是否正确。我立即执行缺少的表达式,我不确定它是否应该从我的游标值中读取,因为它应该去哪里 1.在提出问题之前尝试格式化您的代码。 2. 您应该在从游标中获取数据后构建您的查询(设置 sql_statement 变量)。 3. 您的选择返回 4 列,因此您不应将 tab1_val 和 tab2_val 放入您的INTO
部分 EXECUTE IMMEDIATE
语句中。 4. 如果您使用 INTO,那么您的选择应始终返回一条记录。如果您期望更多结果,您应该使用 BULK COLLECT INTO 和变量,这是一个集合。
我上面的代码可以编译,但实际上并没有插入到匹配表中
你一直在改变你的问题......之前没有关于向表中插入数据......我不知道你的数据,所以很难说为什么没有插入你的桌子。
正如@Wernfried 所写,使用DBMS_OUTPUT.PUT_LINE (sql_statement);
进行调试。你也可以把这个语句的一些输出放在问题中。【参考方案2】:
一定是这样的:
sql_statement := 'SELECT '
|| column1 || ', ' || column2 || ', ' || column3 || ', ' || column4
|| ' FROM ' || table1 || ', ' || table2
|| ' WHERE ' || column1 ||'=' ||column2||'(+)';
EXECUTE IMMEDIATE sql_statement INTO col1_val, col2_val, col3_val, col4_val;
或者最好
sql_statement := 'SELECT '
|| column1 || ', ' || column2 || ', ' || column3 || ', ' || column4
||' FROM '||table1||' LEFT OUTER JOIN '||table2||' ON '||column1||'='||column2;
EXECUTE IMMEDIATE sql_statement INTO col1_val, col2_val, col3_val, col4_val;
对于调试DBMS_OUTPUT.PUT_LINE (sql_statement);
会很有用!
那么你就不需要 Ref-Cursor,只需这样做:
BEGIN
For aRow in (SELECT * FROM a550003.meta_data_table) LOOP
sql_statement := 'SELECT '||aRow.column1||','||aRow.column2 ...
END LOOP;
END;
【讨论】:
嘿 Wernfried 感谢您的帮助,看来这正是我所需要的。我让它工作了,现在如果我想让 sql_staement 写入一个表,我会在(对于 arow 部分)之前做一些类似于插入的事情,我现在还需要执行 sql_statement,就好像我只是把它放入一个编辑器选项卡并运行查询。现在我需要的查询在 DBMS 输出中,但现在我需要把它变成我可以实际运行的东西以上是关于oracle动态查询通过sql获取游标变量的主要内容,如果未能解决你的问题,请参考以下文章