动态识别表(由变量标识的表)

时间:2013-11-11 11:02:12

标签: sql oracle stored-procedures plsql procedure

我正在尝试创建一个允许我动态地将现有行写入另一个表的过程,但下面代码段中的行声明和insert-statement不起作用。错误消息表明虽然输出target_table.table_name可以正常工作,但尚未识别该视图。

稍后会在块中添加更多内容 - 例如带有操作的列(例如INSERT或UPDATE)。这只是一个简单的例子,最后一个程序(pass_reference)用于触发程序。

非常感谢任何帮助。

CREATE OR REPLACE PROCEDURE denormalize (new_cursor sys_refcursor, target_table_name varchar)
IS
target_table user_tables%rowtype;
sql_target_table varchar(200) := 'select * from user_tables where table_name = :target_table_name';
row target_table%rowtype;
BEGIN
  execute immediate sql_target_table into target_table using target_table_name;
  LOOP
    fetch new_cursor into row;
    exit when new_cursor%notfound;
    insert into target_table values row;
    commit;
  END LOOP;
END denormalize;
/

CREATE OR REPLACE PROCEDURE pass_reference
AS
new_cursor sys_refcursor;
BEGIN
open new_cursor for select * from sales where sales_id=1;
denormalize(new_cursor, 'NEW_SALES');
END;
/

1 个答案:

答案 0 :(得分:0)

请检查此代码,它不仅仅是作为例子,因为您在光标中看到的工作列应该被命名为目标表中的列。
我从包中创建html表的视图中获取此代码,希望您发现此示例有用 祝你好运

declare
    in_view_name   varchar2(30);
    in_table_name  varchar2(30) := 'your_new_table';
    out_rc         number;
    out_rc_txt     varchar2(1000);
    l_cursor       number;
    l_sql          varchar2(50) := 'select * from ' || in_view_name;
    l_col_cnt      binary_integer;
    l_col_tab      dbms_sql.desc_tab;
    l_column_value varchar2(4000);
    l_is_empty     boolean := true;
    l_insert_header varchar2(1000);
    l_insert varchar2(32000);
begin
    out_rc     := 0;
    out_rc_txt := 'OK';

    l_cursor := dbms_sql.open_cursor;
    dbms_sql.parse(l_cursor, l_sql, dbms_sql.native);
    l_col_cnt := dbms_sql.execute(l_cursor);
    dbms_sql.describe_columns(l_cursor, l_col_cnt, l_col_tab);

    l_insert_header := 'insert into '||in_table_name||'(';
    if l_col_cnt > 0 then
        -- header
        for i in l_col_tab.first .. l_col_tab.last loop
            dbms_lob.append(l_insert_header, l_col_tab(i).col_name);
            if i != l_col_tab.last then
                dbms_lob.append(l_insert_header, ',');
            end if;
            dbms_sql.define_column(l_cursor, i, l_column_value, 4000);
        end loop;
        l_insert_header := l_insert_header || ') values(';
        -- data
        while dbms_sql.fetch_rows(l_cursor) > 0 loop
            l_is_empty := false;
            l_insert := l_insert_header;
            for i in l_col_tab.first .. l_col_tab.last loop
                dbms_sql.column_value(l_cursor, i, l_column_value);

                l_insert := l_insert || '''' || l_column_value || ''','
                if not in_attachment then
                    dbms_lob.append(out_table, l_td);
                end if;

                if (not in_attachment) or (l_column_value is not null) then
                    dbms_lob.append(out_table, nvl(l_column_value, l_nbsp));
                end if;

                if (not in_attachment) or (i != l_col_tab.last) then
                    dbms_lob.append(out_table, l_tdc);
                end if;
            end loop;
            l_insert := substr(l_insert, 1, length(l_insert) - 1) || ')';
            execute immediate l_insert;
        end loop;
    end if;

    dbms_sql.close_cursor(l_cursor);
end;