2016-10-07 6 views
2

So habe ich dieses Problem, wo ein regulärer PostgreSQL-Ausdruck nicht in zwei verschiedenen Kontexten auf die gleiche Weise verhält - als CONSTRAINT und mit einer regex_matches() -Funktion.PostgreSQL Ziffer passenden Regex seltsames Verhalten

Ich möchte die Regex funktionieren, wie es mit SELECT-Anweisungen unten gezeigt, aber als Tabelle CONSTRAINT, die aus irgendeinem Grund nicht tut.

Hat jemand anderes diese Art von Verhalten erlebt oder hat jemand einen Einblick darauf?

Danke!

CREATE TABLE ExampleTable (
    ID serial, 
    Length char(5) NOT NULL, 

    CONSTRAINT proper_formatting CHECK (Length ~* '\A[0-5]{0,1}\d{1}:[0-5]{1}\d{1}\Z') 
); 

INSERT INTO ExampleTable (Length) VALUES ('03:33'); -- Passes. 
INSERT INTO ExampleTable (Length) VALUES ('3:33'); -- Fails. 

DROP TABLE ExampleTable; 

-- In this context, it works just fine: 
SELECT regexp_matches('03:33', '\A[0-5]{0,1}\d{1}:[0-5]{1}\d{1}\Z'); -- Passes. 
SELECT regexp_matches('3:33', '\A[0-5]{0,1}\d{1}:[0-5]{1}\d{1}\Z'); -- Passes. 
SELECT regexp_matches('93:33', '\A[0-5]{0,1}\d{1}:[0-5]{1}\d{1}\Z'); -- Fails. 
SELECT regexp_matches('531:33', '\A[0-5]{0,1}\d{1}:[0-5]{1}\d{1}\Z'); -- Fails. 
SELECT regexp_matches('3:83', '\A[0-5]{0,1}\d{1}:[0-5]{1}\d{1}\Z'); -- Fails. 

Antwort

1

Verwenden Sie den Typ nicht char(n):

with data(val) as (
values 
    ('03:33'::char(5)), 
    ('3:33'::char(5)), 
    ('3:33') 
) 
select format('==%s==', val), val ~* '\A[0-5]{0,1}\d{1}:[0-5]{1}\d{1}\Z' matches 
from data 

    format | matches 
-----------+--------- 
==03:33== | t 
==3:33 == | f 
==3:33== | t 
(3 rows)  

Siehe auch: PostgreSQL: Difference between text and varchar (character varying)

+0

Zeichen mit unterschiedlichen (5) Spaltentyp funktioniert! Aber kommt es mit einem Performance-Hit? Thanks a bunch :) –

+0

'varchar (5)' ist besser, beachte jedoch, dass du die Länge der Zeichenkette mit 'check' bereits begrenzt hast. Nebenbei verwende ich nur 'text'. Im zitierten Beitrag finden Sie auch einige Benchmarks. – klin

+0

Super, danke :) –