2017-11-24 1 views
0

Ich versuche, eine PL/pgSQL-Funktion mit einem VARCHAR-Argument zu schreiben, das begrenzt werden sollte. Betrachten Sie folgende Funktion, mit einem VARCHAR-Parameter auf eine Größe von 5 Zeichen begrenzt:PL/pgSQL-Funktion mit VARCHAR als Parameter

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

Wenn ich diese Funktion mit einem Text nennen größer als 5 ist, funktioniert es:

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

Es gibt mir die Ergebnis '123456', aber warum? Das sollte mir einen Fehler geben, oder?

Wenn ich definieren eine varchar wie folgt aus:

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

es mir einen Fehler gibt, wie erwartet:

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

ich diesen Fehler wollen geworfen, wenn ein zu großes Argument für die Funktion ist, aber wie?

Antwort

1

Aus historischen Gründen ignoriert PostgreSQL Größenmodifikator im Funktionsargumenttyp (typmod). Es gibt einige Probleme im Zusammenhang mit der Implementierung und einfache und gut genug Lösung ist diese Art Feature zu ignorieren - das erwartete Verhalten ist einfach mit varchar, aber kann ziemlich schwierig sein, korrekt und benutzerfreundlich Verhalten für numerische Typen zu gestalten.

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$ 

Sie können sehen - typmod Wert ist nicht persistent - und hat dann keine Wirkung.

Wenn Sie wirklich einige Grenzen brauchen, dann sollten Sie domain type verwenden:

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) 

Domains sind persistente Typ Synonyme mit allen (typmods, Schecks).

Verwandte Themen