我是 PLSQL 的新手,所以我有一个非常基本的问题,希望有人能帮助我。我想针对 11g 数据库运行直接的 select 语句,然后如果它是 12g 数据库,则对该 SQL 语句进行稍微修改的版本。结果应该输出到屏幕上。在我添加 SQL 语句之前,下面的代码一直有效。我尝试了“立即执行”,但没有奏效,然后使用了游标——但对于多列和多行来说,这不能作为答案,因为它太冗长了。我在这里想念什么?语句可以是任何东西,例如:
--11g
select NAME,OPEN_MODE,DBID from v$database;
--12c
select NAME,OPEN_MODE,DBID,con_id from v$database;
我只想知道如何在这样的代码块中处理任何 SQL 选择语句(返回多行和多列)。谢谢。
DECLARE
v_dbver BINARY_INTEGER;
BEGIN
SELECT TO_NUMBER(SUBSTR(version,1,2)) INTO v_dbver FROM v$instance;
DBMS_OUTPUT.PUT_LINE('Version ='||v_dbver);
IF v_dbver < 12 THEN
DBMS_OUTPUT.PUT_LINE('Running against 11g');
<SQL statement>
ELSIF v_dbver >= 12 THEN
DBMS_OUTPUT.PUT_LINE('Running against 12c');
<SQL statement>
END IF;
END;
/
编辑:请参阅底部的附加说明,了解如何使用 PIPELINE 函数完成此操作。
ORACLE 中的 PL/SQL 不会以与其他 RDBMS 相同的方式返回数据集(如 SQL Server,您可以在块或过程中的任意位置弹出随机 SELECT 语句,并将结果输出到网格)。
Oracle 将仅作为标准 SELECT 查询或通过引用器输出到屏幕。
您正在做的事情被称为匿名块。匿名块不显示 SELECT 语句的结果。它们的存在是为了“完成工作”。我写了一篇博文,稍微解释一下,欢迎大家看看:https ://sqldevdba.com/f/t-sql-vs-plsql-series-part-2-select-into
对于您的问题:您有几个选择,包括:
2. 将结果写入表(使用 Insert INTO ... SELECT FROM),完成后从该表中选择。(在运行报告等计划项目时,这是我的首选方法)。这也将是最快“走出门”的方法,因为您将能够立即查询结果。
对于选项 2(我可能会采用,但您当然不必这样做),它将类似于:
编辑!! 好吧,我的世界已经天翻地覆了。虽然这种方法并不完美,但它肯定会改变一些事情。
在 plsql Oracle10g 上返回多行
此解决方案允许您设置和部署一个函数,并让该函数从 SELECT 语句返回数据集。试一试!!
PL/SQL 不是为编写查询而设计的,因此正如其他人所提到的,您不能只是
select
期望结果集。但是,根据您使用的客户端工具,您可以执行以下操作:通过快速测试,这适用于 SQL*Plus(12c 或更高版本)和 SQL Developer。它在 PL/SQL Developer 14.0.6 中不起作用。
请记住,如果您在 11g 上运行,v$database 没有
con_id
列,因此查询必须是动态的才能编译。您甚至可以动态构建一个完整的查询,而不是两个。编辑:现在我想了想,这对 11g 无论如何都不起作用,因为 11g
dbms_sql
没有return_result
程序,抱歉。但是,这种方法在不需要旧数据库版本的其他情况下可能很有用。在 12c 之前,您可以定义一个 refcursor 变量var rc refcursor
并在块完成后打印它(在 SQL*Plus 等中工作)。