sql >> データベース >  >> RDS >> Oracle

挿入...選択...サブクエリありまたは列順なし

    いいえ、サブクエリを使用してSQLステートメントの一部として列リストを生成することはできません。

    データディクショナリから完全なステートメントを生成できます:

    select 'insert into cl ("'
      || listagg(column_name, '","') within group (order by column_id)
      || '") select "'
      || listagg(column_name, '","') within group (order by column_id)
      || '" from clt'
    from user_tab_columns where table_name = 'CLT';
    

    次に、それをコピーして貼り付けるか、匿名ブロックから動的SQLを使用します。

    declare
      stmt varchar2(4000);
    begin
      select 'insert into cl ("'
        || listagg(column_name, '","') within group (order by column_id)
        || '") select "'
        || listagg(column_name, '","') within group (order by column_id)
        || '" from clt'
      into stmt
      from user_tab_columns where table_name = 'CLT';
    
      dbms_output.put_line(stmt); -- to check and debug
      execute immediate stmt;
    end;
    /
    

    ダミーテーブルがいくつかあります:

    create table clt (col1 number, col2 date, col3 varchar2(10));
    create table cl (col3 varchar2(10), col1 number, col2 date);
    
    insert into clt (col1, col2, col3) values (42, date '2018-07-12', 'Test');
    
    insert into cl
    select * from clt;
    
    SQL Error: ORA-00932: inconsistent datatypes: expected NUMBER got DATE
    

    そのブロックを実行すると、次のようになります。

    insert into cl ("COL1","COL2","COL3") select "COL1","COL2","COL3" from clt
    
    PL/SQL procedure successfully completed.
    
    select * from cl;
    
    COL3             COL1 COL2      
    ---------- ---------- ----------
    Test               42 2018-07-12
    

    また、これが頻繁に実行する可能性が高い場合は、その匿名ブロックを2つのテーブル名を使用するプロシージャに変換することもできます(再利用可能である必要があると述べましたが、同じテーブルを意味する可能性があります。スクリプト内のブロック)。

    さらに進んで、両方のテーブルに表示される列のみを含めるか、データ型が完全に一致することを確認することもできます。それはもう少し手間がかかり、必要ないかもしれませんが。




    1. PostgresqlのFOUND_ROWS()関数に相当します

    2. zip形式のCSV(filename.csv.gz)ファイルをPostgreSQLテーブルにロードしています

    3. 長さが10未満の文字列を格納する場合、varchar(10)とvarchar(1000)に違いはありますか?

    4. mysqlクエリからPythonスクリプトを実行する方法は?