这个问题类似于我在StackOverflow上找到的其他几个问题,但这些差异对于我来说是一个非常重要的保证一个新问题,所以这里是:
我想从Oracle中的动态SQL获取结果集,然后在类似SqlDeveloper的工具中将其显示为结果集,就像我直接执行动态SQL语句一样。这在SQL Server中很简单,所以具体来说,这是SQL Server中一个在SQL Server Management Studio或Query Explorer中返回结果集的示例:
EXEC sp_executesql N'select * from countries'
或更恰当地说:
DECLARE @stmt nvarchar(100)
SET @stmt = N'select * from countries'
EXEC sp_executesql @stmt
问题"How to return a resultset / cursor from a Oracle PL/SQL anonymous block that executes Dynamic SQL?"解决了问题的前半部分 - 将动态SQL执行到游标中。问题"How to make Oracle procedure return result sets"提供了类似的答案。网络搜索揭示了同一主题的许多变化,所有这些只涉及我问题的前半部分。我发现this post解释了如何在SqlDeveloper中执行此操作,但它使用了SqlDeveloper的一些功能。我实际上使用自定义查询工具,所以我需要在SQL代码中自包含该解决方案。此自定义查询工具同样无法显示print(dbms_output.put_line)语句的输出;它只显示结果集。这里还有one more possible avenue使用'execute immediate ... bulk collect',但是这个例子再次使用dbms_output.put_line语句的循环呈现结果。 This link尝试解决这个问题,但问题从未在那里得到解答。
假设这是可能的,我将添加一个条件:我想这样做而不必定义函数或过程(由于有限的DB权限)。也就是说,我想执行一个包含动态SQL的自包含PL / SQL块,并在SqlDeveloper或类似工具中返回结果集。
总结一下:
有什么建议吗?
答案 0 :(得分:0)
尝试尝试这些。
DECLARE
TYPE EmpCurTyp IS REF CURSOR;
v_emp_cursor EmpCurTyp;
emp_record employees%ROWTYPE;
v_stmt_str VARCHAR2(200);
v_e_job employees.job%TYPE;
BEGIN
-- Dynamic SQL statement with placeholder:
v_stmt_str := 'SELECT * FROM employees WHERE job_id = :j';
-- Open cursor & specify bind argument in USING clause:
OPEN v_emp_cursor FOR v_stmt_str USING 'MANAGER';
-- Fetch rows from result set one at a time:
LOOP
FETCH v_emp_cursor INTO emp_record;
EXIT WHEN v_emp_cursor%NOTFOUND;
END LOOP;
-- Close cursor:
CLOSE v_emp_cursor;
END;
declare
v_rc sys_refcursor;
begin
v_rc := get_dept_emps(10); -- This returns an open cursor
dbms_output.put_line('Rows: '||v_rc%ROWCOUNT);
close v_rc;
end;
在此处查找更多示例。 http://forums.oracle.com/forums/thread.jspa?threadID=886365&tstart=0
答案 1 :(得分:0)
在TOAD执行下面的脚本时,系统会提示您输入v_result的类型。从类型选择光标的选择列表中,结果随后显示在Toad的数据网格中(excel电子表格,如结果)。也就是说,当使用游标作为结果时,您应该总是编写两个程序(客户端和服务器)。在这种情况下,'TOAD'将成为客户。
DECLARE
v_result sys_refcursor;
v_dynamic_sql VARCHAR2 (4000);
BEGIN
v_dynamic_sql := 'SELECT * FROM user_objects where ' || ' 1 = 1';
OPEN :v_result FOR (v_dynamic_sql);
END;
Oracle的SQL Developer中可能还有类似的机制来提示绑定。
答案 2 :(得分:0)
你似乎要求一大块PL / SQL代码,它将采用任意查询返回未确定结构的结果集和'forward / restructure'结果集,以某种方式可以很容易地呈现一些“自定义GUI工具“。
如果是这样,请查看DBMS_SQL以获取动态SQL。它有一个DESCRIBE_COLUMNS过程,它从动态SELECT语句返回列。您需要的步骤是,
作为替代方法,您可以尝试将查询构建到XMLFOREST语句中,并将结果解析为XML。
补充: 与SQL Server不同,Oracle PL / SQL调用不会“自然地”返回单个结果集。它可以打开一个或多个ref游标并将它们传递回客户端。然后,客户端负责从这些ref游标中获取记录和列。如果您的客户端没有/不能处理,那么您不能使用PL / SQL调用。 存储的函数可以返回预定义的集合类型,这可以允许您执行类似“select * from table(func_name('select * from countries'))”的操作。但是,该函数不能执行DML(更新/删除/插入/合并),因为它会破坏该查询的任何一致性概念。此外,返回的结构是固定的,以便
select * from table(func_name('select * from countries'))
必须返回与
相同的列(列名和数据类型)select * from table(func_name('select * from persons'))
使用DBMS_SQL或XMLFOREST,这样的函数可以采用动态查询并将其重组为预定义的列集(col_1,col_2等),以便可以以一致的方式返回它。但我看不出它的意义。
答案 3 :(得分:0)