使用立即执行在循环中分配多个字段

Assigning multiple fields in a loop using execute immediate

我正在使用 PLPDF 的库为各种文件创建电子表格 - 我正在尝试编写一个程序来获取每个字段的值并将它们逐个插入到电子表格中。此操作可以包括许多不同的 table 进入许多不同的电子表格,因此仅进行导出并不能减少它。

这个例子有两个从 tables 创建的游标 - USER_TAB_COLUMNS 到 select 列名和实际视图查询以拉取数据。我有一个循环逐条记录地遍历数据,第二个循环在记录中逐个字段。

在实际写入电子表格 blob 之前,我只是 运行 dbms_output.putline 以确保我获得了所需的数据。

declare

    q_str varchar2(100);
    this_vc varchar2(3000);

    cursor diet_table is 
        select * from vcars_diet where nhp_id = 8573;

    cursor diet_stru is
        select 'begin :1 := i.' || column_name || '; end;' line_o_code from user_tab_columns where table_name = 'VCARS_DIET';

begin
    for i in diet_table loop

        DBMS_OUTPUT.PUT_LINE ('--------------------------------------------------------'); 
        for h in diet_stru loop

            DBMS_OUTPUT.PUT_LINE ('Varchar Value for i: "' || h.line_o_code || '"'); 
            EXECUTE IMMEDIATE (h.line_o_code) USING out this_vc;
            DBMS_OUTPUT.PUT_LINE ('Varchar Value for i.' || h.line_o_code || ' is: '||this_vc); 

        end loop;
    end loop;
end;

diet table 中的字段是:

NHP_ID
DATE_TIME
DIET_NO
FORM_NAME
DATA_TYPE 

结果是:

ORA-06550: line 1, column 13: PLS-00201: identifier 'I.NHP_ID' must be declared ORA-06550: line 1, column 7: PL/SQL: Statement ignored ORA-06512: at line 33 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error. *Action:

我从 AskTom article 中复制了 Connor McDonald's 解决方案中的 PL/SQL 代码。 它使用动态类型 SQL 来解析任何 SQL 查询并将列名和值转换为一个集合。我在 HR 模式中对员工 table 使用了示例查询。将其替换为您的查询。

set serverout on size 999999
set verify off
declare
    p_query varchar2(32767) := 
              q'{select * from employees 
                          where rownum = 1
                 }';-- Here you put your query  
    l_theCursor     integer default dbms_sql.open_cursor;
    l_columnValue   varchar2(4000);
    l_status        integer;
    l_descTbl       dbms_sql.desc_tab;
    l_colCnt        number;
    n number := 0;
  procedure p(msg varchar2) is
    l varchar2(4000) := msg;
  begin
    while length(l) > 0 loop
      dbms_output.put_line(substr(l,1,80));
      l := substr(l,81);
    end loop;
  end;
begin
    execute immediate
    'alter session set nls_date_format=''dd-mon-yyyy hh24:mi:ss'' ';

    dbms_sql.parse(  l_theCursor,  p_query, dbms_sql.native );
    dbms_sql.describe_columns( l_theCursor, l_colCnt, l_descTbl );

    for i in 1 .. l_colCnt loop
        dbms_sql.define_column(l_theCursor, i, l_columnValue, 4000);
    end loop;

    l_status := dbms_sql.execute(l_theCursor);

    while ( dbms_sql.fetch_rows(l_theCursor) > 0 ) loop
        for i in 1 .. l_colCnt loop
            dbms_sql.column_value( l_theCursor, i, l_columnValue );
            p( 'Value for '|| l_descTbl(i).col_name
              || ' is: ' || 
              l_columnValue );
        end loop;
        dbms_output.put_line( '-----------------' );
        n := n + 1;
    end loop;
    if n = 0 then
      dbms_output.put_line( chr(10)||'No data found '||chr(10) );
    end if;
end;
/

这给出了输出:

Value for EMPLOYEE_ID is: 198
Value for FIRST_NAME is: Donald
Value for LAST_NAME is: OConnell
Value for EMAIL is: DOCONNEL
Value for PHONE_NUMBER is: 650.507.9833
Value for HIRE_DATE is: 21-jun-2007 00:00:00
Value for JOB_ID is: SH_CLERK
Value for SALARY is: 2600
Value for COMMISSION_PCT is: 
Value for MANAGER_ID is: 124
Value for DEPARTMENT_ID is: 50
-----------------


PL/SQL procedure successfully completed.