首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >PLSQL输出多列和多行信息

PLSQL输出多列和多行信息
EN

Database Administration用户
提问于 2021-06-23 17:16:23
回答 2查看 2.9K关注 0票数 0

我是PLSQL的新手,所以我有一个非常基本的问题,我希望有人能帮助我。如果SQL语句是12g数据库,我想对11g DB运行一个直接的select语句,然后稍微修改该SQL语句的版本。结果应该输出到屏幕上。下面的代码可以工作,直到我添加SQL语句。我试过‘立即执行’,但这不起作用,然后使用游标-但对于多列和多行,这不可能是答案,因为它是长缠绕。我在这里错过了什么?这些语句可以是任何内容,例如:

代码语言:javascript
运行
复制
--11g
select NAME,OPEN_MODE,DBID from v$database; 
--12c
select NAME,OPEN_MODE,DBID,con_id from v$database;

我只想知道如何处理这样一个代码块中的任何SQL select语句(返回多行和多个cols)。谢谢。

代码语言:javascript
运行
复制
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');
    
ELSIF v_dbver >= 12 THEN
    DBMS_OUTPUT.PUT_LINE('Running against 12c');
    
END IF;
END;
/
EN

回答 2

Database Administration用户

回答已采纳

发布于 2021-06-23 17:39:16

编辑:请参阅底部的附加注释,了解如何使用管道函数来完成此操作。

ORACLE中的PL/SQL不像其他RDBMS那样返回数据集(就像Server一样,您可以在块或过程中的任何地方弹出一个随机的SELECT语句,它会将结果输出到网格中)。

Oracle将只作为标准的SELECT查询或通过一个refcursor输出到屏幕上。

你所做的被称为匿名块。匿名块不显示SELECT语句的结果。他们的存在是为了“完成工作”。我写了一篇博文,对此做了一些解释,欢迎大家来看看:https://sqldevdba.com/f/t-sql-vs-plsql-series-part-2-select-into

关于您的问题:您有几种选择,包括:

  1. 使用RefCursor输出Select语句。(https://oracle-base.com/articles/misc/using-ref-cursors-to-return-recordsets)

2.将结果写入表(使用Insert .,然后在完成时从该表中选择。(这是我在运行像报表这样的排定项目时首选的方法)。这也是最快的“走出家门”的方法,因为这样您就可以立即查询结果。

  1. 使用结果集将每条记录打印到DBMS_OUTPUT (yuck)
  2. 使用游标遍历结果集的每个记录,并将数据写入csv文件。

对于选项2(我可能会采取,但您当然不必这么做),它应该是这样的:

代码语言:javascript
运行
复制
--If you have an existing table (TableName) that you always want to use
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);
    
    --This table needs to exist already, so you'll have to have created it ahead of time
    TRUNCATE TABLE TableNameHere; --Truncate the table to remove artifacts
    
IF v_dbver < 12 THEN
    DBMS_OUTPUT.PUT_LINE('Running against 11g');
    --11g
    INSERT INTO TableName
    (NAME,OPEN_MODE,DBID)
    SELECT NAME,OPEN_MODE,DBID 
    FROM v$database; 
    
ELSIF v_dbver >= 12 THEN
    DBMS_OUTPUT.PUT_LINE('Running against 12c');
    --12c
    INSERT INTO TableName
    (NAME,OPEN_MODE,DBID,con_id)
    SELECT NAME,OPEN_MODE,DBID,con_id 
    FROM v$database;
END IF;
END;


--If you want it to DYNAMICALLY create the table:


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);
    
    --This table needs to exist already, so you'll have to have created it ahead of time
    TRUNCATE TABLE TableNameHere; --Truncate the table to remove artifacts
    
IF v_dbver < 12 THEN
    DBMS_OUTPUT.PUT_LINE('Running against 11g');
    --11g
    CREATE TABLE TableName_Timestamp --This will auto-create the table 
    AS
    SELECT NAME,OPEN_MODE,DBID 
    FROM v$database; 
    
ELSIF v_dbver >= 12 THEN
    DBMS_OUTPUT.PUT_LINE('Running against 12c');
    --12c
    CREATE TABLE TableName_Timestamp --This will auto-create the table 
    AS
    SELECT NAME,OPEN_MODE,DBID,con_id 
    FROM v$database;
END IF;
END;

<#>EDIT!!好吧,我的世界被颠覆了。虽然这种方法并不完美,但它确实改变了一些事情。

在plsql Oracle10g上返回许多行

此解决方案允许您设置和部署函数,并使该函数从SELECT语句返回数据集。试试看!!

票数 1
EN

Database Administration用户

发布于 2021-06-26 09:39:32

PL/SQL不是为编写查询而设计的,因此,正如其他人所提到的,您不能只使用select并期望得到一个结果集。但是,根据您正在使用的客户端工具,您可能可以这样做:

代码语言:javascript
运行
复制
declare
    rc sys_refcursor;
begin
    if dbms_db_version.ver_le_12 then open rc for
        select name,open_mode,dbid from v$database; 
    else open rc for
        'select name,open_mode,dbid,con_id from v$database';
    end if;

    dbms_sql.return_result(rc);
end;

通过快速测试,这可以在SQL*Plus (12c或更高版本)和中工作。它不适用于PL/SQL Developer 14.0.6。

请记住,如果您是针对11g运行的,v$database没有con_id列,因此查询必须是动态的,以便进行编译。您甚至可以动态地构造一个完整的查询,而不是有两个查询。

编辑:现在我已经考虑过了,this无论如何也不能对11g运行,因为11g的dbms_sql没有return_result过程,对不起。但是,这种方法在不需要遗留数据库版本的其他情况下可能很有用。在12c之前,您可以使用var rc refcursor定义一个refcursor变量,并在块完成后打印它(在SQL*Plus中工作,等等)。

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/294719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档