是否有可能从PL / SQL块输出一个SELECT状态?

我如何得到一个PL / SQL块来输出一个SELECT语句的结果,就像我做了一个普通的SELECT

例如,如何做一个SELECT如:

 SELECT foo, bar FROM foobar; 

提示:

 BEGIN SELECT foo, bar FROM foobar; END; 

不起作用。

这取决于你需要什么结果。

如果您确定只有一行,请使用隐式游标:

 DECLARE v_foo foobar.foo%TYPE; v_bar foobar.bar%TYPE; BEGIN SELECT foo,bar FROM foobar INTO v_foo, v_bar; -- Print the foo and bar values dbms_output.put_line('foo=' || v_foo || ', bar=' || v_bar); EXCEPTION WHEN NO_DATA_FOUND THEN -- No rows selected, insert your exception handler here WHEN TOO_MANY_ROWS THEN -- More than 1 row seleced, insert your exception handler here END; 

如果要select多于一行,则可以使用显式游标:

 DECLARE CURSOR cur_foobar IS SELECT foo, bar FROM foobar; v_foo foobar.foo%TYPE; v_bar foobar.bar%TYPE; BEGIN -- Open the cursor and loop through the records OPEN cur_foobar; LOOP FETCH cur_foobar INTO v_foo, v_bar; EXIT WHEN cur_foobar%NOTFOUND; -- Print the foo and bar values dbms_output.put_line('foo=' || v_foo || ', bar=' || v_bar); END LOOP; CLOSE cur_foobar; END; 

或使用其他types的游标:

 BEGIN -- Open the cursor and loop through the records FOR v_rec IN (SELECT foo, bar FROM foobar) LOOP -- Print the foo and bar values dbms_output.put_line('foo=' || v_rec.foo || ', bar=' || v_rec.bar); END LOOP; END; 

您可以在Oracle 12.1或更高版本中执行此操作:

 declare rc sys_refcursor; begin open rc for select * from dual; dbms_sql.return_result(rc); end; 

我没有12.x数据库或DBVisualizer进行testing,但这应该是您的出发点。

有关更多详细信息,请参阅Oracle 12.1新增function指南中的隐式结果集, Tom Kyte的博客 , Oracle Base等

对于较早的版本,根据工具,您可以使用引用绑定variables,如SQL * Plus中的示例:

 set autoprint on var rc refcursor begin open :rc for select count(*) from dual; end; / PL/SQL procedure successfully completed. COUNT(*) ---------- 1 1 row selected. 

在包中创build一个函数并返回一个SYS_REFCURSOR:

 FUNCTION Function1 return SYS_REFCURSOR IS l_cursor SYS_REFCURSOR; BEGIN open l_cursor for SELECT foo,bar FROM foobar; return l_cursor; END Function1; 

从匿名块? 我现在想更多的了解你认为需要的情况,因为有了子查询保理子句和内联视图,很less有你需要使用PL / SQL来处理最复杂情况以外的事情。

如果您可以使用命名过程,则使用stream水线function。 这里是一个从文档中拉出的例子:

 CREATE PACKAGE pkg1 AS TYPE numset_t IS TABLE OF NUMBER; FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED; END pkg1; / CREATE PACKAGE BODY pkg1 AS -- FUNCTION f1 returns a collection of elements (1,2,3,... x) FUNCTION f1(x NUMBER) RETURN numset_t PIPELINED IS BEGIN FOR i IN 1..x LOOP PIPE ROW(i); END LOOP; RETURN; END; END pkg1; / -- pipelined function is used in FROM clause of SELECT statement SELECT * FROM TABLE(pkg1.f1(5)); 

传统的“Hello World!”块包含一个可执行部分,该部分调用DBMS_OUTPUT.PUT_LINE过程在屏幕上显示文本:

 BEGIN DBMS_OUTPUT.put_line ('Hello World!'); END; 

您可以在此处查看: http : //www.oracle.com/technetwork/issue-archive/2011/11-mar/o21plsql-242570.html

您需要使用本机dynamicSQL。 另外,您不需要BEGIN-END来运行SQL命令:

 declare l_tabname VARCHAR2(100) := 'dual'; l_val1 VARCHAR2(100):= '''foo'''; l_val2 VARCHAR2(100):= '''bar'''; l_sql VARCHAR2(1000); begin l_sql:= 'SELECT '||l_val1||','||l_val2||' FROM '||l_tabname; execute immediate l_sql; dbms_output.put_line(l_sql); end; / Output: SELECT 'foo','bar' FROM dual 

如果你想看到在pl / sql中select查询输出,你需要使用一个明确的游标。 它将保存活动的数据集,并通过每次获取每一行,只要它从循环迭代中获取数据集中的logging,就会显示活动数据集中的所有logging。 这些数据不会以表格forms生成,这个结果将以纯文本格式。 希望这会有所帮助。 对于任何其他查询,你可能会问….

 set serveroutput on; declare cursor c1 is select foo, bar from foobar; begin for i in c1 loop dbms_output.put_line(i.foo || ' ' || i.bar); end loop; end; 

这取决于你需要什么结果。

如果您确定只有一行,请使用隐式游标:

 DECLARE v_foo foobar.foo%TYPE; v_bar foobar.bar%TYPE; BEGIN SELECT foo,bar FROM foobar INTO v_foo, v_bar; - Print the foo and bar values dbms_output.put_line('foo=' || v_foo || ', bar=' || v_bar); EXCEPTION WHEN NO_DATA_FOUND THEN - No rows selected, insert your exception handler here WHEN TOO_MANY_ROWS THEN - More than 1 row seleced, insert your exception handler here END; 

如果要select多于一行,则可以使用显式游标:

 DECLARE CURSOR cur_foobar IS SELECT foo, bar FROM foobar; v_foo foobar.foo%TYPE; v_bar foobar.bar%TYPE; BEGIN - Open the cursor and loop through the records OPEN cur_foobar; LOOP FETCH cur_foobar INTO v_foo, v_bar; EXIT WHEN cur_foobar%NOTFOUND; - Print the foo and bar values dbms_output.put_line('foo=' || v_foo || ', bar=' || v_bar); END LOOP; CLOSE cur_foobar; END; 

或使用其他types的游标:

 BEGIN - Open the cursor and loop through the records FOR v_rec IN (SELECT foo, bar FROM foobar) LOOP - Print the foo and bar values dbms_output.put_line('foo=' || v_rec.foo || ', bar=' || v_rec.bar); END LOOP; END; 

对于12c以下的版本,简单的答案是NO ,至less不是以SQL Server的方式完成。
您可以打印结果,可以将结果插入到表格中,可以将结果作为游标从函数/过程中返回,也可以从函数返回行集合 –
但是你不能执行SELECT语句,而无需执行结果。


SQL Server

 begin select 1+1 select 2+2 select 3+3 end 

/ *返回3个结果集* /


神谕

 SQL> begin 2 select 1+1 from dual; 3 end; 4 / select * from dual; * ERROR at line 2: ORA-06550: line 2, column 1: PLS-00428: an INTO clause is expected in this SELECT statement 

使用执行立即声明

喜欢:

 declare var1 integer; var2 varchar2(200) begin execute immediate 'select emp_id,emp_name from emp' into var1,var2; dbms_output.put_line(var1 || var2); end; 
Interesting Posts