2009-02-23 31 views
5

我想要一個解決方案來強制執行一個約束,只有當列不爲空。我似乎無法找到在文檔中執行此操作的方法。只有在Postgresql中列不爲空的情況下,如何強制實施約束?

create table mytable(
    table_identifier_a INTEGER, 
    table_identifier_b INTEGER, 
    table_value1,...) 

別對數據的性質,我將具有標識符B和當在創建表的值。在我們收到額外的數據後,我將能夠填充標識符a。在這一點上,我想確保一個unique key of (identifier_a, value1),但只有當identifier_a存在。

希望有道理,任何人有任何想法?

回答

6

嗯。唯一約束不會阻止多個NULL值。

CREATE TABLE mytable (
    table_identifier_a INTEGER NULL, 
    table_identifier_b INTEGER NOT NULL, 
    table_value1   INTEGER NOT NULL, 

    UNIQUE(table_identifier_a, table_identifier_b) 
); 

請注意,我們可以插入muliple空值到它,甚至當identifier_b 比賽:

test=# INSERT INTO mytable values(NULL, 1, 2); 
INSERT 0 1 
test=# INSERT INTO mytable values(NULL, 1, 2); 
INSERT 0 1 
test=# select * from mytable; 
table_identifier_a | table_identifier_b | table_value1 
--------------------+--------------------+-------------- 
        |     1 |   2 
        |     1 |   2 
(2 rows) 

但是我們不能創建重複的(A,B)對:

test=# update mytable set table_identifier_a = 3; 
ERROR: duplicate key value violates unique constraint "mytable_table_identifier_a_key" 

當然,你確實有一個問題:你的表沒有主鍵。你 可能有一個數據模型問題。但你沒有提供足夠的 細節來解決這個問題。

+0

數據模型問題不是我的,它的客戶:)!謝謝。 – 2009-03-03 20:05:44

0

您可以使用觸發器而不是約束來處理此問題。

0

如果我是你,我會把表分成兩個表,並可能創建視圖,根據需要組合它們。

1

如果它是一個事務中完成整個操作是可行的,它可以改變其Postgres的時間評估約束,即:

START; 
SET CONSTRAINTS <...> DEFERRED; 
<SOME INSERT/UPDATE/DELETE> 
COMMIT; 

在這種情況下,約束在提交進行評價。參見: Postgres 7.4 Doc - Set constraintsPostgres 8.3 Doc

1

其實,我可能會把它分解成兩個表格。你正在建模兩種不同的東西。第一個是最初的版本,這只是部分的,第二個是整個事情。一旦需要將第一種東西帶到第二種的信息,將該行從一個表移到另一個表。

相關問題