【问题标题】:Assigning multiple fields in a loop using execute immediate使用立即执行在循环中分配多个字段
【发布时间】:2019-08-27 11:31:35
【问题描述】:

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

这个例子有两个从表中创建的游标——USER_TAB_COLUMNS用来选择列名,实际的视图查询用来拉取数据。我有一个循环逐条遍历数据记录,第二个循环逐个字段地遍历记录。

在对电子表格 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;

饮食表中的字段是:

NHP_ID
DATE_TIME
DIET_NO
FORM_NAME
DATA_TYPE 

结果是:

ORA-06550:第 1 行,第 13 列: PLS-00201:必须声明标识符“I.NHP_ID” ORA-06550:第 1 行,第 7 列: PL/SQL:语句被忽略 ORA-06512:在第 33 行 06550. 00000 - “第 %s 行,第 %s 列:\n%s” *原因:通常是 PL/SQL 编译错误。 *行动:

【问题讨论】:

    标签: sql plsql execute-immediate


    【解决方案1】:

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

    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.
    

    【讨论】:

    • 该过程将完全符合我的要求。我必须被授予在我的个人测试区域使用 dbms_sql 包的权利,但它会满足要求。谢谢!!!
    • @KenSheldon:不客气。如果您发现答案有用,请考虑accepting,这样它也可以帮助其他人。另请阅读this
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    相关资源
    最近更新 更多