ORACLE:从 SELECT * 结果构建“INSERT INTO”语句

问题描述 投票:0回答:1

这里是 PL/SQL 初学者。我正在尝试构建一个脚本,该脚本从表“ADMIN.ACCT_HRS”中获取结果并为每一行创建 INSERT INTO 语句,以便我可以在另一台服务器上重建该表。 ACCT_HRS 的搜索参数是“WID”,我使用用户输入的值“pknum”从“ADMIN.INVENTORY”表中提取该参数。这个脚本仍处于起步阶段,所以我只针对一张表;但最终,我计划对其进行调整,以便为六个不同的表生成 INSERT INTO 语句,其中只有一个用户输入的值,所有这些表的行数和列数都在不断变化。所以它必须是动态的。

到目前为止,我的脚本如下所示:

DECLARE
-- declare variables for pkNum input and for SQL statement output
v_pkNum VARCHAR2(16);
v_sqlBuild VARCHAR2(4000);
v_sqlOutput VARCHAR2(4000);

BEGIN
-- prompt for pkNum value
DBMS_OUTPUT.PUT_LINE('pkNum:');
v_pkNum := '&pkNum';

-- initialize the output statement
v_sqlBuild := 'INSERT INTO ACCT_HRS (';

-- create a list that stores the columns from table 
FOR col IN (SELECT column_name FROM all_tab_columns WHERE table_name = 'ACCT_HRS' AND owner = 'ADMIN') LOOP       
    v_sqlBuild := v_sqlBuild || col.column_name || ', ';
END LOOP;

-- trim the trailing comma and add VALUES keyword
v_sqlBuild := RTRIM(v_sqlBuild, ', ') || ') VALUES (';


/* generate INSERT INTO statement*/
-- loop to iterate through rows in table
FOR row IN (SELECT * FROM ADMIN.ACCT_HRS WHERE WID IN (SELECT WID FROM ADMIN.INVENTORY WHERE pkNum = v_pkNum)) LOOP

    -- Reset the value part of the SQL statement
    v_sqlOutput := v_sqlBuild;
    
    -- loop to iterate through each cell in row
    FOR cell IN (SELECT column_name FROM all_tab_columns WHERE table_name = 'ACCT_HRS' AND owner = 'ADMIN') LOOP
        v_sqlOutput := v_sqlOutput || cell[row.column_name] || ', ';
    END LOOP;

    -- trim the trailing comma and add closing parenthesis
    v_sqlOutput := RTRIM(v_sqlOutput, ', ') || ');';

    -- print the INSERT INTO statement
    DBMS_OUTPUT.PUT_LINE(v_sqlOutput);

END LOOP;

END;
/

sql oracle loops plsql database-cursor
1个回答
0
投票

我可以提出替代建议吗,因为这样可以避免重新发明轮子。如果您使用免费客户端 SQLcl,它可以轻松处理这个问题,例如

SQL> select * from dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

SQL> set sqlformat insert

SQL> select * from dept;

REM INSERTING into DEPT
SET DEFINE OFF;
Insert into DEPT (DEPTNO,DNAME,LOC) values (10,'ACCOUNTING','NEW YORK');
Insert into DEPT (DEPTNO,DNAME,LOC) values (20,'RESEARCH','DALLAS');
Insert into DEPT (DEPTNO,DNAME,LOC) values (30,'SALES','CHICAGO');
Insert into DEPT (DEPTNO,DNAME,LOC) values (40,'OPERATIONS','BOSTON');

或者直接在给定的 SQL 中执行

SQL> select /*insert*/ * from dept;
REM INSERTING into DEPT
SET DEFINE OFF;
Insert into DEPT (DEPTNO,DNAME,LOC) values (10,'ACCOUNTING','NEW YORK');
Insert into DEPT (DEPTNO,DNAME,LOC) values (20,'RESEARCH','DALLAS');
Insert into DEPT (DEPTNO,DNAME,LOC) values (30,'SALES','CHICAGO');
Insert into DEPT (DEPTNO,DNAME,LOC) values (40,'OPERATIONS','BOSTON');

但是,如果您确实想自己构建它,这里有一个视频,展示了如何处理更多数据类型并创建运行速度更快的脚本的各种技术。它还涵盖了 SQLcl

https://youtu.be/LdGtl09C6DM

© www.soinside.com 2019 - 2024. All rights reserved.