PostgreSQL:コマンドラインからパラメーターを渡す方法は?


92

?プレースホルダーを使用するスクリプトにやや詳細なクエリがあります。この同じクエリをpsqlコマンドライン(スクリプトの外部)から直接テストしたかったのです。入力してすべて?を実際の値で置き換えるのを避けたいのですが、クエリの後に引数を渡したいのです。

例:

SELECT  * 
FROM    foobar
WHERE   foo = ?
   AND  bar = ?
    OR  baz = ?  ;

次のようなものを探します:

%> {select * from foobar where foo=? and bar=? or baz=? , 'foo','bar','baz' };

コンテキストを増やしてください。このクエリは、SQLファイル、Perl / Python / Ruby / <ここにお気に入りのスクリプト言語を挿入>スクリプト、または他の場所にありますか?

@ジャック:私はこれをpsqlプロンプト(コマンドライン)から直接実行しようとしています。スクリプトからコードを取得していますが、検索/置換プロセス全体を実行したくありません。
vol7ron、2011

@ Vol7ron、psqlコマンドラインの例については、以下の私の回答を参照してください。
MAbraham1

1
@ MAbraham1:いいね。質問の背景をもう少し説明する必要がありました。オープンテキストにSQLを含むスクリプトがたくさんあります。それらを取得し、デバッグ用のカスタム値を使用してデータベースに直接ヒットすることが役立つ場合があります。追加のファイルを保存する必要がないPostgres内で簡単にそれを行う方法を探していました。
vol7ron 2012

@ Vol7ron、ありがとう。バッチジョブについて考えていましたが、オープンSQLでもトークンを使用できるはずです。私の答えが気に入ったら、投票することを忘れないでください。
MAbraham1 2012

回答:


178

-v構文を使用できます。

psql -v v1=12  -v v2="'Hello World'" -v v3="'2010-11-12'"

そしてSQLの変数を:v1、:v2などとして参照します

select * from table_1 where id = :v1;

2つの引用符を使用して文字列/日付の値を渡す方法に注意してください " '...' "


2
+1興味深い、名前付き引数を渡します。ログイン後にこれを行う方法を知っていますか?
vol7ron 2011

9
もちろん、そのまま使用してください\set v3 'another value'。あなたは、SQL文で値を引用する必要があるときだけ、覚えて、使用は、このように、周りの変数名をアポストロフィ:SELECT * FROM foo WHERE bar = :'v3';
Cromax

1
私は彼らがそれを手に入れたと思いますawk
ニール・マクギガン2017年

1
代わりに@を使用できます:sqlserverのように
Awais Mahmood

4
これを読んだとき、私は-vで設定された変数が-cで実行されたコマンドで利用可能になることを期待していましたが、そうではないことに注意してください。つまり、 psql -v v1=12 -v v2="'Hello World'" -v v3="'2010-11-12'" -c 'select * from table_1 where id = :v1;' 構文エラーが発生します。ただし、bashがシェルの場合は、次のことを試してみてください psql -v v1=12 -v v2="'Hello World'" -v v3="'2010-11-12'" <<< 'select * from table_1 where id = :v1;'
Malcook

30

PostgreSQLで発見されたので、スクリプト言語と同じようにPREPAREステートメントを実行できます。残念ながら、まだは使用できませんが?$n表記法は使用できます。

上記の例を使用:

PREPARE foo(text,text,text) AS
    SELECT  * 
    FROM    foobar
    WHERE   foo = $1
       AND  bar = $2
        OR  baz = $3  ;
EXECUTE foo('foo','bar','baz');
DEALLOCATE foo;

@IvanBlackあなたがそれに含めるつもりだった何か他にありましたか?:)割り当て解除はセッションの最後に自動的に実行されます
vol7ron

現在fooはビジー状態でありPREPARE、現在のセッションが閉じられていない間は別の名前が必要になることに注意してください。あなたPREPAREpsqlそれに慣れると、新しい名前を毎回発明するのは難しくDEALLOCATE、それを助けることができます=)
Ivan Black

これについて言及していただきありがとうございます。私はしばらくPREPAREを使用していませんが、それは有用な情報です
vol7ron

このソリューションはIMOに非常に適しています。便利な副作用-準備されたステートメントを複数回簡単に呼び出すことができます。
Yuri

13

psqlには、

\set name val

コマンド、-v name=valコマンドラインオプションに関連付けられることになっています。引用は面倒です。ほとんどの場合、クエリ全体をシェルのヒアドキュメントに入れる方が簡単です。

編集する

おっと、私は(フォーマットオプション用)の-v代わりに、-P以前の返答が正しいと言ったはずです。


7

また、psqlコマンドラインで、またはバッチファイルからパラメーターを渡すこともできます。最初のステートメントは、データベースに接続するために必要な詳細を収集します。

最後のプロンプトは制約値を要求します。これはWHERE column IN()句で使用されます。文字列の場合は単一引用符で囲み、コンマで区切ることを忘れないでください。

@echo off
echo "Test for Passing Params to PGSQL"
SET server=localhost
SET /P server="Server [%server%]: "

SET database=amedatamodel
SET /P database="Database [%database%]: "

SET port=5432
SET /P port="Port [%port%]: "

SET username=postgres
SET /P username="Username [%username%]: "

SET /P bunos="Enter multiple constraint values for IN clause [%constraints%]: "
ECHO you typed %constraints%
PAUSE
REM pause
"C:\Program Files\PostgreSQL\9.0\bin\psql.exe" -h %server% -U %username% -d %database% -p %port% -e -v v1=%constraints% -f test.sql

次にSQLコードファイルで、WHERE句内、またはSQLの他の任意の場所にv1トークンを追加します。トークンは、ファイルだけでなく、開いているSQLステートメントでも使用できることに注意してください。これをtest.sqlとして保存します。

SELECT * FROM myTable
WHERE NOT someColumn IN (:v1);

Windowsでは、ファイル全体をDOS BATchファイル(.bat)として保存し、test.sqlを同じディレクトリに保存して、バッチファイルを起動します。

EnterpriseDBのDave Page、元のプロンプトスクリプトをありがとう。


Windowsの例では+1。ほとんどのPgデータベースは* nixバリアントで存在します
vol7ron '26

2

コマンドラインから直接質問することはできないようです。plpgsqlでユーザー定義関数を使用するか、スクリプト言語からクエリを呼び出す必要があります(後者の方法では、SQLインジェクションを避けるのが少し簡単になります)。


私ではありませんでした-匿名のままにしても、投票には何らかの説明が必要になることを望みます(質問を閉じるために投票する理由と同様)。
vol7ron
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.