我有一個編碼爲'UTF8'的Postgresql 9.3數據庫。但是,數據庫中有一列不應包含除ASCII以外的任何內容。如果非ascii進入,它會導致我無法控制的另一個系統出現問題。因此,我想爲該列添加約束。注意:我已經有了一個BEFORE INSERT觸發器 - 所以這可能是一個檢查的好地方。Postgresql約束檢查非ASCII字符
在PostgreSQL中完成此操作的最佳方式是什麼?
我有一個編碼爲'UTF8'的Postgresql 9.3數據庫。但是,數據庫中有一列不應包含除ASCII以外的任何內容。如果非ascii進入,它會導致我無法控制的另一個系統出現問題。因此,我想爲該列添加約束。注意:我已經有了一個BEFORE INSERT觸發器 - 所以這可能是一個檢查的好地方。Postgresql約束檢查非ASCII字符
在PostgreSQL中完成此操作的最佳方式是什麼?
您可以定義ASCII
爲ordinal 1 to 127
爲了這個目的,因此下面的查詢將確定爲「非ASCII」值的字符串:
SELECT exists(SELECT 1 from regexp_split_to_table('abcdéfg','') x where ascii(x) not between 1 and 127);
,但它不可能是超高效,而且使用的子查詢會迫使你在觸發器而不是CHECK約束中執行它。
相反,我會使用正則表達式。如果你想所有可打印字符那麼您可以在檢查約束使用範圍,如:
CHECK (my_column ~ '^[ -~]*$')
this will match everything from the space to the tilde,這是可打印的ASCII範圍。
如果你想所有的ASCII,打印和不可打印,您可以use byte escapes:
CHECK (my_column ~ '^[\x00-\x7F]*$')
最嚴格正確的方法是convert_to(my_string, 'ascii')
,讓如果失敗的異常升高......但PostgreSQL不提供ascii
(即7位)編碼,所以這種方法是不可能的。
使用圍繞regular expression構建的CHECK約束。
假設你的意思是某列不應該包含什麼,但小寫字母從一個到ž,大寫字母從一個到ž,以及數字通過 ,像這樣的東西應該工作。
alter table your_table
add constraint allow_ascii_only
check (your_column ~ '^[a-zA-Z0-9]+$');
這是當他們談論「只有ASCII」相對於數據庫列人們通常意味着,但ASCII還包括標點符號字形,算術運算符,等你想允許去之間的字符方括號。