【问题标题】:A more efficient way to do a select insert that involves over 300 columns?一种更有效的方式来进行涉及超过 300 列的选择插入?
【发布时间】:2016-03-11 00:44:30
【问题描述】:

我正在尝试找到一种更有效的方法来编写 PL/SQL 查询 从具有 300 多列的表中选择插入到该表的备份版本(相同的列名 + 2 个额外的列)。

我可以简单地在脚本中输入所有列名(下面的示例),但是有这么多的名字,我会很困扰... :(

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

提前致谢

【问题讨论】:

  • 正如 Jarlh 所说,您可以使用 INSERT INTO TABLE_TEMP SELECT * FROM [TABLE] WHERE id = USER_ID,但前提是您的 TABLE_TEMP 列与 TABLE 结构 @andre3wap 的顺序相同
  • @jarlh - 这是一个很好的方法。我面临的唯一问题是;因为TABLE_TEMP 有2 个额外的列不在TABLE 上,我如何用你的方法排除这2 个列。我确实从查询中删除了它们,但我得到了invalid identifier and not enough values 错误
  • 为这两个额外的列指定字面量/null。
  • @jarlh - 非常感谢,您应该将其发布为答案,以便我接受。
  • 不能归一化的...

标签: sql plsql


【解决方案1】:

为这两个额外的列指定字面量/null。

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

【讨论】:

    【解决方案2】:

    你可以很容易地为任何给定的表格建立一个列列表:

    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
    

    这应该让你几乎到达你需要的地方。

    【讨论】:

      【解决方案3】:

      问题标签上写着 plsql,它是 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;
      

      这会导致以下输出:

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

      格式很好:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-17
        • 1970-01-01
        • 2019-04-08
        • 1970-01-01
        • 1970-01-01
        • 2023-01-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多