PL / pgSQLで使用される「$$」とは


93

PL / pgSQLに完全に新しいので、この関数の 2つのドル記号の意味は何ですか。

CREATE OR REPLACE FUNCTION check_phone_number(text)
RETURNS boolean AS $$
BEGIN
  IF NOT $1 ~  e'^\\+\\d{3}\\ \\d{3} \\d{3} \\d{3}$' THEN
    RAISE EXCEPTION 'Wrong formated string "%". Expected format is +999 999';
  END IF;
  RETURN true; 
END;
$$ LANGUAGE plpgsql STRICT IMMUTABLE;

私はそれを推測している、ではRETURNS boolean AS $$$$プレースホルダです。

最後の行は少し謎です: $$ LANGUAGE plpgsql STRICT IMMUTABLE;

ちなみに、最後の行はどういう意味ですか?


4
この質問への答えとしてアーウィン応答をマークご検討ください、彼の説明は、実際には何かを説明し$$、あなたがそれを読んで何か新しいことを学ぶことができます例えばもあります$foo$
csharpfolk

回答:


135

ドル記号はドルの引用に使用され、関数定義に固有​​のものではありません。これは、SQLスクリプト内の実質的にどこでも単一引用符を置き換えるために使用できます。

関数の本体は、単一引用符で囲む必要がある文字列リテラルです。ドル引用は、関数本体内の引用の問題を回避するために、単一引用符のPostgreSQL固有の代替です。関数の定義を一重引用符で書くこともできます。しかし、その場合は、本文のすべての単一引用符をエスケープする必要があります。

CREATE OR REPLACE FUNCTION check_phone_number(text)
RETURNS boolean AS
'
BEGIN
  IF NOT $1 ~  e''^\\+\\d{3}\\ \\d{3} \\d{3} \\d{3}$'' THEN
    RAISE EXCEPTION ''Malformed string "%". Expected format is +999 999'';
  END IF;
  RETURN true; 
END
' LANGUAGE plpgsql STRICT IMMUTABLE;

これはそれほど良い考えではありません。代わりにドル引用$$符を使用してください。具体的には、トークンをの間に置いて一意にします。関数本体の内部でも$引用符を使用することをお勧めします。私は実際にそれをたくさんします。

CREATE OR REPLACE FUNCTION check_phone_number(text)
  RETURNS boolean  
AS
$func$
BEGIN
 ...
END
$func$  LANGUAGE plpgsql STRICT IMMUTABLE;

詳細:

2番目の質問について
は、最も優れたマニュアルCREATE FUNCTIONを読んで、例の最後の行を理解してください。


1
あなたは素晴らしいマニュアルと言うべきです、RTEMはそれに正しいリングを持っていません:)
muが短すぎる

@muistooshort:悪いことに、テーマのバリエーションを試したところ、調和が崩れたようです。RTMEMはどうですか?:)
Erwin Brandstetter 2012

1
私はそれを叫んでみました、そしてそれはちょうど同じではありませんでした。ただし、礼儀正しさが重視される状況もあります。
muが短すぎる

@ErwinBrandstetterわかりましたが、何$body$ですか?からCREATE OR REPLACE FUNCTION update_ts() RETURNS TRIGGER AS $BODY$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $BODY$ LANGUAGE plpgsql- bodyどこにも定義がありません。私はここで何が起こっているのか本当に分かりません
グロウラー

2
@Growler:$body$私が説明したように、単に「ドルの見積もり」です。詳細:stackoverflow.com/a/12320729/939860
Erwin Brandstetter 2017

21

$$は、関数定義の開始と終了を示すために使用する区切り文字です。以下を検討してください。

CREATE TABLE <name> <definition goes here> <options go here, eg: WITH OIDS>

create関数の構文は似ていますが、関数内ですべての種類のSQL(特にステートメントの終わり、文字)を使用するため、区切り文字を指定しないと、パーサーが作動します。したがって、ステートメントは次のように読む必要があります。

CREATE OR REPLACE FUNCTION check_phone_number(text)
RETURNS boolean AS <code delimited by $$> LANGUAGE plpgsql STRICT IMMUTABLE;

実際の定義の後のものは、データベースに関数に関するより多くの情報を提供するオプションであり、その使用を最適化できます。

実際、マニュアルの「4.1.2.2。ドル引用文字列定数」を参照すると、ドル記号の間に文字を使用することもでき、すべて1つの区切り文字として数えられることがわかります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.