A personal identity codes consist of a string of numbers that indicates the individual’s date of birth, an individualized string, and a control character.
Example: 150600A905P
• 150600 = Date of birth
• A = the character in the middle
• 905 = the individualized string
• P = Control character
-
The control character is either a number or a letter.
The calculation formula is to divide the value of the nine-digit string made up by the date of birth and the individualized string by 31. Then the value of the division’s remainder determines the control character. Remainders are from 0->30 and the corresponding control character are [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, H, J, K, L, M, N, P, R, S, T, U, V, W, X, Y] -
The character in the middle : The convention for the mid-character is:
• Year of birth in 1800’s → + (the plus sign),
• Year of birth in 1900’s → – (minus sign) and Y, X, W, V, U (capital letters)
• Year of birth in 2000’s → A, B, C, D, E, F (capital letters).
How to create a check constraint in Postgres for the volunteer table with a function that validates a volunteer ID when a new volunteer is inserted. The ID is valid if they satisfies:
- Length = 11 characters
- The 7th character (separator) is one of the following: +, -, A, B, C, D, E, F, X, Y, W, V, U
- The correct control character is used
The constraint does not work as expected. What’s wrong with my logic?
3
Answers
-- Create a function to calculate the control character
-- Add a check constraint to the Volunteer table
What you are asking for validating a column value before insert, and if it fails than return some sort of error, in this case you can create a check constraint which calls a custom function to validate volunteer_id:
Your table can look somewhat look like:
if table already exists than:
before running this you will have to check all existing data meets the criteria already or the alter statement will fail.
Now regarding the custom function:
Now when you will try to insert a new row it will be validated by the validate_volunteer_id function. If the volunteer_id does not meet the criteria, the insert will fail with a constraint violation error.
Hope this is what you were looking for
Function
You could fix your function (errors marked with
!!!
):But most of it is just noise. Boils down to:
Basically picks an array element according to the position computed with your formula.
Using the short syntax of standard SQL functions. See:
Add appropriate function labels. In this case:
IMMUTABLE
,PARALLEL SAFE
,STRICT
. The first two are crucial for performance! See:Postgres arrays are 1-based by default. The modulo operator
%
returns 0-based. You can either add 1, or work with a custom-index array (cheaper). See:Don’t use the data type
char(n)
. See:CHECK
constraintAlso a bit cheaper and shorter:
You could even just use the expression from my condensed function directly without creating a function at all.
Just remember to document what you are doing and why, either way.