【问题标题】:Print multiple rows from select statement从 select 语句中打印多行
【发布时间】:2017-10-07 14:54:54
【问题描述】:

我有这张桌子:

|      Pattern       | 
---------------------- 
|category    |varchar|
|patternexpr |varchar|

例如,在此表中,我可以有一个类别 ISBN 及其模式来识别它。

我想创建一个带有三个参数的过程:一个表 T、其中一个列 C 和一个类别。我想打印 T 表中 C 列中尊重相关模式的每一行。

这就是我所做的(更新为正确答案):

CREATE OR REPLACE PROCEDURE Recognize(T varchar,C varchar,catego varchar)
IS
    v_patt Pattern.CATEGOR%Type;

BEGIN
    SELECT patternexpr INTO v_patt
    FROM Pattern WHERE CATEGOR=catego;

    FOR myrow IN (SELECT C FROM T WHERE REGEXP_LIKE(C, v_patt) LOOP
      dbms_output.put_line(myrow.C);
    END LOOP;

END;
/

如何在不知道“DECLARE”位置的变量 patt 的值的情况下声明一个游标来打印我的结果?我应该在第一个查询之后添加另一个声明并开始...结束块吗?最好的方法是什么?

(我正在研究 Oracle SGBD)

【问题讨论】:

    标签: sql oracle plsql procedure


    【解决方案1】:

    为此目的使用REF CURSOR 获取记录。

    CREATE OR REPLACE PROCEDURE Recognize(
        T      VARCHAR2,
        C      VARCHAR2,
        catego VARCHAR2)
    IS
      v_patt Pattern.CATEGOR%Type;
      v_cur_txt VARCHAR2(400);
    TYPE cur_type
    IS
      REF
      CURSOR;
        v_cur cur_type;
        v_c VARCHAR2(20);
      BEGIN
        SELECT patternexpr INTO v_patt FROM Pattern WHERE CATEGOR=catego;
      v_cur_txt := 'SELECT '||C||' FROM '|| T ||'  WHERE REGEXP_LIKE('||C||', '''||v_patt||''')';
      OPEN v_cur FOR v_cur_txt;
      LOOP
        FETCH v_cur INTO v_c;
        EXIT
      WHEN v_cur%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(v_c);
      END LOOP;
      CLOSE v_cur;
    END;
    /
    

    注意::在您的代码中为 NO_DATA_FOUND 等包含正确的 EXCEPTION 处理。此外,根据 Nicholas ,使用 dbms_assert 包进行一些验证

    【讨论】:

    • @Gatsby 当您使用普通连接构造一个动态查询
    【解决方案2】:

    在 Oracle 中,您不需要显式游标:

    for myrow in (select c from t where regexp_like(c, patt) loop
        dbms_output.put_line(myrow.c);
    end loop;
    

    我会将模式变量称为v_patt;这样,声明的变量就不会与列名混淆。

    【讨论】:

    • 我在调用该过程时遇到了问题,我的参数被解释为字符,所以它不会打印任何东西......我这样称呼它:execute Recognize('T','col ','ISBN');
    • @Gatsby 。 . .一点也不。每个数据库都有自己的脚本语言。至于你专栏中的问题,我建议你再问一个问题。看来您最初的问题已经解决了。
    • @Gatsby 它怎么可能很好用?您将表名和列名作为字符传递给您的过程,并使用静态 SQL 来查询该表。除非您的架构中有一个名为 T 的表,否则该过程根本不会编译。
    • @NicholasKrasnov 。 . .我不太确定你指的是什么,但你可能会看这个问题。它将表称为T
    • 我指的是T作为varchar数据类型的参数传入。
    猜你喜欢
    • 1970-01-01
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    相关资源
    最近更新 更多