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

DOブロック内でpsqlメタコマンドによって設定された変数を使用します

    回答

    DO 文字列リテラルが必要です plpgsqlコードを使用します。記号はpsqlの文字列内で置換されません。
    文字列全体をpsql変数に連結して、次に 実行します。

    • psql変数を連結する方法は?

    (ドキュメントごとに)次の理由により、かなり複数行のフォーマットは不可能です:

    ただし、いずれの場合も、メタコマンドの引数は行末を超えて続行できません。

    簡単な例:

    test=# \set value foo
    test=# \set do 'BEGIN\n   RAISE NOTICE ''v: %'', ' :'value' ';\nEND'
    test=# DO :'do';
    NOTICE:  v: foo
    

    改行を\nに置き換えます (または、きれいな形式を気にしない場合は削除してください)。この適合コードに基づく:

    DO
    '
    DECLARE
       _val  text;
       _vals text[] := string_to_array(>>values<<, '','');
    BEGIN
       FOREACH _val IN ARRAY _vals
       LOOP
         RAISE NOTICE ''v: %'', _val;
       END LOOP;
    END
    '
    

    次のようになります:

    test=# \set do 'DECLARE\n   _val  text;\n   _vals text[] := string_to_array(' :'values' ', '','');\nBEGIN\n   FOREACH _val IN ARRAY _vals\n   LOOP\n     RAISE NOTICE ''v: %'', _val;\n   END LOOP;\nEND'
    test=# DO :'do';
    NOTICE:  v: foo
    NOTICE:  v: bar
    NOTICE:  v: baz
    DO

    太字を追加しました 見つけやすくするために変数を強調します。

    サーバーセッション変数を使用した@Pavel(ab)による関連回答:

    • PL / PGSQLからのセッション変数(\ set var ='value')の参照

    代替ソリューション

    プリペアドステートメント

    現在のソリューションはそれほど悪くはありません。簡単にします:

    PREPARE get_values AS SELECT * FROM regexp_split_to_table(:'values', ',');
    
    DO
    $do$
    DECLARE
       _val text;
    BEGIN
       FOR _val IN EXECUTE
          'EXECUTE get_values'
       LOOP
          RAISE NOTICE 'v: %', _val;
       END LOOP;
    END
    $do$;
    

    一時的なテーブル

    一時テーブルを使用した同様のソリューション:

    CREATE TEMP TABLE tmp AS SELECT * FROM regexp_split_to_table(:'values', ',') v;
    
    DO
    $do$
    DECLARE
       _val text;
    BEGIN
       FOR _val IN
          TABLE tmp
       LOOP
          RAISE NOTICE 'v: %', _val;
       END LOOP;
    END
    $do$;
    


    1. selectステートメントでのSQL内部結合

    2. AWSRDSMySQLで低速クエリログを有効にする方法

    3. 例を使用してSQLSELECTの使用方法を学ぶ

    4. 非推奨のmysql_*関数を使用して古いmysql-phpコードを正常に書き換える方法は?