5

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

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

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 感谢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;
         /
4

3 回答 3

4

你可以用DBMS_SQL包做到这一点。

更新 要获得有关 DBMS_SQL 的更多详细参考,请转到此处

于 2013-05-30T21:31:42.450 回答
0

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

于 2013-05-30T23:23:59.393 回答
0

<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>

于 2017-11-21T12:14:10.387 回答