简体   繁体   English

一种更有效的方法来进行涉及300列以上的选择插入?

[英]A more efficient way to do a select insert that involves over 300 columns?

I am trying to find a more efficient way to write PL/SQL Query to to select insert from a table with 300+ columns, to the back up version of that table (same column names + 2 extra columns). 我正在尝试找到一种更高效的方式来编写PL / SQL查询,以从具有300多个列的表中选择插入到该表的备份版本(相同的列名+ 2个额外的列)。

I could simply type out all the column names in the script (example below), but with that many names, it will bother me... :( 我可以简单地在脚本中键入所有列名(下面的示例),但是具有那么多的名称,这会困扰我... :(

INSERT INTO 
   TABLE_TEMP 
   (column1, column2, column3, etc)
(SELECT column1, column2, column3, etc FROM TABLE WHERE id = USER_ID);

Thanks in advance 提前致谢

Specify literals/null for those two extra columns. 为这两个额外的列指定文字/空值。

INSERT INTO 
   TABLE_TEMP 
SELECT t1.*, null, null FROM TABLE t1 WHERE id = USER_ID

You can pretty easily build a column list for any given table: 您可以轻松地为任何给定的表构建一个列列表:

select table_catalog
    ,table_schema
    ,table_name
    ,string_agg(column_name, ', ' order by ordinal_position)
from information_schema.columns
where table_catalog = 'catalog_name'
    and table_schema = 'schema_name'
    and table_name = 'table_name'
group by table_catalog
    ,table_schema
    ,table_name

That should get you nearly where you need to be. 那应该使您几乎需要达到的位置。

The question tag says plsql, which is Oracle or one of its variants. 问号说的是plsql,它是Oracle或其变体之一。 Here is an example of doing it in Oracle: 这是在Oracle中执行此操作的示例:

drop table brianl.deleteme1;
drop table brianl.deleteme2;

CREATE TABLE brianl.deleteme1
(
   a     INTEGER
 , b     INTEGER
 , c     INTEGER
 , efg   INTEGER
);

CREATE TABLE brianl.deleteme2
(
   b     INTEGER
 , c     INTEGER
 , d     INTEGER
 , efg   INTEGER
);

DECLARE
   l_ownerfrom   VARCHAR2 (30) := 'BRIANL';
   l_tablefrom   VARCHAR2 (30) := 'DELETEME1';
   l_ownerto     VARCHAR2 (30) := 'BRIANL';
   l_tableto     VARCHAR2 (30) := 'DELETEME2';
   l_comma       VARCHAR2 (1) := NULL;
BEGIN
   DBMS_OUTPUT.put_line ('insert into ' || l_ownerto || '.' || l_tableto || '(');

   FOR eachrec IN (  SELECT f.column_name
                       FROM all_tab_cols f INNER JOIN all_tab_cols t ON (f.column_name = t.column_name)
                      WHERE f.owner = l_ownerfrom
                        AND f.table_name = l_tablefrom
                        AND t.owner = l_ownerto
                        AND t.table_name = l_tableto
                   ORDER BY f.column_name)
   LOOP
      DBMS_OUTPUT.put_line (l_comma || eachrec.column_name);
      l_comma   := ',';
   END LOOP;

   DBMS_OUTPUT.put_line (') select ');
   l_comma   := NULL;

   FOR eachrec IN (  SELECT f.column_name
                       FROM all_tab_cols f INNER JOIN all_tab_cols t ON (f.column_name = t.column_name)
                      WHERE f.owner = l_ownerfrom
                        AND f.table_name = l_tablefrom
                        AND t.owner = l_ownerto
                        AND t.table_name = l_tableto
                   ORDER BY f.column_name)
   LOOP
      DBMS_OUTPUT.put_line (l_comma || eachrec.column_name);
      l_comma   := ',';
   END LOOP;

   DBMS_OUTPUT.put_line (' from ' || l_ownerfrom || '.' || l_tablefrom || ';');
END;

This results in this output: 结果为:

insert into BRIANL.DELETEME2(
B
,C
,EFG
) select
B
,C
,EFG
from BRIANL.DELETEME1;

Nicely formatted: 格式正确:

INSERT INTO brianl.deleteme2 (b, c, efg)
   SELECT b, c, efg
     FROM brianl.deleteme1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM