2

I need to created domain in PostgreSQL for a price. The price must be NUMERIC(9,2) where 9 is precision and 2 - scale. When trying to create domain getting:

ERROR: operator does not exist: numeric ~* unknown Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.

QUERY:

CREATE DOMAIN d_price AS NUMERIC(9, 2) NOT NULL 
CONSTRAINT Product_price_can_contain_only_double_precision_value
CHECK(VALUE ~*'^(([[:digit:]])+\.([[:digit:]]){2})$');
5
  • Cast your numeric to TEXT. Eg. (VALUE::TEXT ~ '^(([[:digit:]])+\.([[:digit:]]){2})$'). You do not need the case-insensitive symbole (*) either. More details at postgresql.org/docs/current/static/functions-matching.html Commented Dec 30, 2013 at 23:13
  • 4
    What's the use of the check constraint? That does not make any sense. A numeric column won't let you store non-numeric values anyway Commented Dec 30, 2013 at 23:30
  • @a_horse_with_no_name: I need numeric value in specific form, something like: [0-9]+\.[0-9]{2} . Ex: 25.10 ; 199999.00 Commented Dec 30, 2013 at 23:39
  • 4
    Agree with @a_horse_with_no_name -- numbers do not have a format except when converted to text in a particular way. The constraint does nothing. Commented Dec 30, 2013 at 23:52
  • I think this might be a case of trying to define a number in terms of text, when range may be a better option. What is the min and max value of this numeric? A range check constraint makes much more sense for a number. Would that work? Commented Dec 31, 2013 at 1:39

2 Answers 2

5

You need your numeric value as a string before you can use the string operator, change your VALUE to: CAST(VALUE AS TEXT)

Sign up to request clarification or add additional context in comments.

1 Comment

For those who use it with JPA, you can use CAST(VALUE AS string).
4

Your CHECK constraint is nonsensical, because it applies after the value has already been converted to NUMERIC by the database engine's number parser.

VALUE ~*'^(([[:digit:]])+\.([[:digit:]]){2})$')

appears to say "one or more leading digits, a period, and exactly two trailing digits". You can't do that check in any useful way once the number has already been parsed. Observe:

regress=> SELECT NUMERIC(18,2) '1', NUMERIC(18,2) '1.12345';
 numeric | numeric 
---------+---------
    1.00 |    1.12
(1 row)

No matter what the input is, if it fits inside the NUMERIC you've specified, it'll be extended to fit. If it doesn't fit the NUMERIC size you've given it'll produce an error before your CHECK constraint ever runs.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.