【问题标题】:Oracle : how to fetch data from dynamic query?Oracle:如何从动态查询中获取数据?
【发布时间】:2013-05-30 21:00:21
【问题描述】:

我有一个程序可以根据输入生成动态查询字符串。此查询可以从我的数据库中的任何表或连接表中进行选择,并且列名和列数是未知的。

现在用这个查询字符串作为唯一的输入,我想从结果中获取所有数据并逐行输出,有什么办法吗?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 感谢 Thinkjet 的参考。我已经解决了这个问题,为了帮助其他人,这是我使用的一段代码:

        DECLARE
           v_curid    NUMBER;
           v_desctab  DBMS_SQL.DESC_TAB;
           v_colcnt   NUMBER;
           v_name_var  VARCHAR2(10000);
           v_num_var   NUMBER;
           v_date_var  DATE;
           v_row_num    NUMBER;
            p_sql_stmt VARCHAR2(1000);
        BEGIN
            v_curid := DBMS_SQL.OPEN_CURSOR;
            p_sql_stmt :='SELECT * FROM emp';
            DBMS_SQL.PARSE(v_curid, p_sql_stmt, DBMS_SQL.NATIVE);
           DBMS_SQL.DESCRIBE_COLUMNS(v_curid, v_colcnt, v_desctab);

           -- Define columns:
           FOR i IN 1 .. v_colcnt LOOP
            IF v_desctab(i).col_type = 2 THEN
                DBMS_SQL.DEFINE_COLUMN(v_curid, i, v_num_var);
                ELSIF v_desctab(i).col_type = 12 THEN
                DBMS_SQL.DEFINE_COLUMN(v_curid, i, v_date_var);
                ELSE
                DBMS_SQL.DEFINE_COLUMN(v_curid, i, v_name_var, 50);
                END IF;
            END LOOP;
            v_row_num := dbms_sql.execute(v_curid);
            -- Fetch rows with DBMS_SQL package:
            WHILE DBMS_SQL.FETCH_ROWS(v_curid) > 0 LOOP
                FOR i IN 1 .. v_colcnt LOOP
                IF (v_desctab(i).col_type = 1) THEN
                        DBMS_SQL.COLUMN_VALUE(v_curid, i, v_name_var);
                ELSIF (v_desctab(i).col_type = 2) THEN
                        DBMS_SQL.COLUMN_VALUE(v_curid, i, v_num_var);
                ELSIF (v_desctab(i).col_type = 12) THEN
                        DBMS_SQL.COLUMN_VALUE(v_curid, i, v_date_var);
                END IF;
            END LOOP;
            END LOOP;
            DBMS_SQL.CLOSE_CURSOR(v_curid);
         END;
         /

【问题讨论】:

  • 可以从 f.ex 获得的表格列。 dba_tab_columns,构建动态查询并使用REF CURSOR。如果出现问题,请编辑注释并发布您的代码,以便我们尽力为您提供帮助。

标签: sql oracle plsql


【解决方案1】:

您可以使用DBMS_SQL 包做到这一点。

更新 要获取有关 DBMS_SQL 的更详细参考,请转到 here

【讨论】:

    【解决方案2】:

    如果您在 PL/SQL 中构建字符串,可以使用 EXECUTE IMMEDIATE. BULK COLLECT INTO 并输出集合。

    【讨论】:

    • 你想如何使用EXECUTE IMMEDIATE从返回多行的查询中获取数据?
    【解决方案3】:

    <PRE>
    DECLARE
       RUN_S         CLOB;
       IGNORE        NUMBER;
       SOURCE_CURSOR NUMBER;
       PWFIELD_COUNT NUMBER DEFAULT 0;
       L_DESCTBL     DBMS_SQL.DESC_TAB2;
       Z_NUMBER      NUMBER;
    BEGIN
       RUN_S         := ' SELECT 1      AS VAL1,
                                 2      AS VAL2,
                                 CURSOR (SELECT 11 AS VAL11,
                                                12 AS VAL12
                                           FROM DUAL) AS CUR1,
                                 CURSOR (SELECT 11 AS VAL11,
                                                12 AS VAL12
                                           FROM DUAL) AS CUR2
                            FROM DUAL';
       SOURCE_CURSOR := DBMS_SQL.OPEN_CURSOR;
       DBMS_SQL.PARSE(SOURCE_CURSOR, RUN_S, DBMS_SQL.NATIVE);
       DBMS_SQL.DESCRIBE_COLUMNS2(SOURCE_CURSOR, PWFIELD_COUNT, L_DESCTBL); -- get record structure
       FOR I IN 1 .. PWFIELD_COUNT LOOP
          DBMS_OUTPUT.PUT_LINE('Col ' || I || ' Type:' || L_DESCTBL(I).COL_TYPE);
          IF L_DESCTBL(I).COL_TYPE = 2 THEN
             DBMS_SQL.DEFINE_COLUMN(SOURCE_CURSOR, I, Z_NUMBER);
          END IF;
          NULL;
      END LOOP;
       IGNORE := DBMS_SQL.EXECUTE(SOURCE_CURSOR);
       LOOP
          IF DBMS_SQL.FETCH_ROWS(SOURCE_CURSOR) > 0 THEN
             FOR I IN 1 .. PWFIELD_COUNT LOOP
                IF L_DESCTBL(I).COL_TYPE IN (2) THEN
                   DBMS_SQL.COLUMN_VALUE(SOURCE_CURSOR, I, Z_NUMBER);
                   DBMS_OUTPUT.PUT_LINE('Col ' || I || ' Value:' || Z_NUMBER);
                END IF;
             END LOOP;
          ELSE
             EXIT;
          END IF;
       END LOOP;
    END;
    </PRE>

    【讨论】:

    • 如何使用 CURSOR TYPE COLUMN 从 SQL 中获取价值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 2015-02-05
    • 2020-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多