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

PostgreSQL関数内のpsql変数のエスケープ構文はありますか?

    PSQL SET 変数は、ドルで引用された文字列内では補間されません。これは確かにはわかりませんが、SETをオンにするためのエスケープやその他のトリックはないと思います。 そこに可変補間があります。

    引用符で囲まれていない:userをくさびで留めることができると思うかもしれません。 希望する効果を得るために、2ドルで引用されたPL/pgSQLのストレッチの間。しかし、これは機能していないようです...構文には、文字列を連結する式ではなく、単一の文字列が必要だと思います。誤解されるかもしれません。

    とにかく、それは問題ではありません。別のアプローチがあります(Pascoが指摘したように):PL/pgSQL引数を受け入れるようにストアドプロシージャを記述します。これがどのように見えるかです。

    CREATE OR REPLACE FUNCTION foo("user" TEXT) RETURNS void AS
    $$
    BEGIN
            EXECUTE 'GRANT SELECT ON my_table TO GROUP ' || quote_ident(user);
    END;    
    $$ LANGUAGE plpgsql;
    

    この機能に関する注意事項:

    1. EXECUTE 適切なGRANTを生成します プロシージャ引数を使用して、呼び出しごとに。 「「動的コマンドの実行 」 "EXECUTEについて説明します 詳細。
    2. プロシージャ引数の宣言user 二重引用符で囲む必要があります。二重引用符は、識別子として解釈されるように強制します。

    このように関数を定義すると、補間されたPSQL変数を使用して関数を呼び出すことができます。概要は次のとおりです。

    1. psql --variable user="'whoever'" --file=myscript.sqlを実行します 。ユーザー名は一重引用符で囲む必要があります!
    2. myscript.sqlで、上記のような関数を定義します。
    3. myscript.sqlに、select foo(:user);を配置します。 。これは、userの値に入力した一重引用符に依存する場所です。 。

    これはうまくいくように見えますが、それはかなり不気味に私を襲います。 SETと思いました 変数はランタイム構成を目的としていました。 SETでデータを持ち運ぶ 奇妙に思えます。

    編集しない具体的な理由は次のとおりです。 SETを使用する 変数。マンページから:「これらの割り当ては起動の非常に早い段階で行われるため、内部目的で予約された変数は後で上書きされる可能性があります。」 Postgresがuserという名前の変数を使用することを決定した場合 (またはあなたが選んだものは何でも)、それはあなたのスクリプト引数をあなたが意図していなかったもので上書きする可能性があります。実際、psqlはすでにUSERを取ります それ自体のために-これはSETのためにのみ機能します 大文字と小文字が区別されます。これは最初からほとんど物事を壊しました!



    1. 操作'='の照合(utf8mb4_unicode_ci、IMPLICIT)と(utf8mb4_general_ci、IMPLICIT)の不正な組み合わせ

    2. リモートサイトに条件付きでロゴを提供する

    3. Postgresエラー:式として使用されるサブクエリによって返される複数の行

    4. PythonでMySQLデータベースに挿入した後にIDを取得するにはどうすればよいですか?