2017-11-24 14 views
0

PL/pgSQL関数をVARCHAR引数で記述しようとしていますが、これは制限する必要があります。 5つの文字のサイズに制限VARCHARパラメーターを指定して、機能を次の点を考慮PL/pgSQL関数でVARCHARをパラメータとして使用

CREATE OR REPLACE FUNCTION do_nothin(v_value VARCHAR(5)) 
RETURNS TEXT AS 
$$ 
DECLARE 
BEGIN 
    RETURN v_value; 
END; 
$$ 
LANGUAGE plpgsql; 

私は5よりも大きいテキストでこの関数を呼び出すと、それが作業を行います。

DO $$ 
DECLARE 
BEGIN 
    PERFORM do_nothin('123456'); 
END; 
$$ 

それは私に与えます結果 '123456'、なぜですか?これは私に誤りの権利を与えるべきですか?

私はこのようなvarchar型定義する場合:

DO $$ 
DECLARE 
    v_mytext VARCHAR(5); 
BEGIN 
    v_mytext := '123456'; 
END; 
$$ 

を期待どおりには私にエラーを与える:関数の大きすぎる引数がある場合に

ERROR: value too long for type character varying(5) CONTEXT: PL/pgSQL  function inline_code_block line 5 at assignment SQL state: 22001 

は、私はこのエラーがスローされたいです、しかしどのように?

答えて

1

PostgreSQLは歴史的な理由から、関数の引数型(typmod)でサイズ変更子を無視します。実装に関連するいくつかの問題があり、シンプルで十分な解決策はこのタイプの機能を無視していることです。予想される動作はvarcharでは単純ですが、数値型に対して正しくユーザーフレンドリな振る舞いを設計するのはかなり困難です。

create or replace function fx(a varchar(10)) 
returns varchar as $$ begin return a; end $$ language plpgsql; 

postgres=# \sf fx 
CREATE OR REPLACE FUNCTION public.fx(a character varying) 
RETURNS character varying 
LANGUAGE plpgsql 
AS $function$ begin return a; end $function$ 

- typmodの値は永続的ではないことがわかります。その後は効果がありません。あなたが実際にいくつかの制限が必要な場合

、あなたはdomain typeを使用する必要があります。

postgres=# create domain varchar_10 as varchar(10); 
CREATE DOMAIN 
postgres=# create or replace function fx2(a varchar_10) 
returns varchar as $$ begin return a; end $$ language plpgsql 
CREATE FUNCTION 
postgres=# select fx2('12345678901'); 
ERROR: value too long for type character varying(10) 

ドメインはすべて(typmods、小切手)との永続的なタイプの同義語です。

関連する問題