2012-08-15 69 views
53

下面的示例表結構給出了一個錯誤:沒有唯一的約束與參考表的給定鍵匹配,並且一直盯着它,現在我無法弄清楚在這種情況下出現這種錯誤的原因。什麼是導致錯誤:沒有唯一的約束匹配參考表給定的鍵?

BEGIN; 

CREATE TABLE foo (
    name    VARCHAR(256) PRIMARY KEY 
); 

CREATE TABLE bar(
    pkey  SERIAL PRIMARY KEY, 
    foo_fk  VARCHAR(256) NOT NULL REFERENCES foo(name), 
    name  VARCHAR(256) NOT NULL, 
    UNIQUE (foo_fk,name) 
); 

CREATE TABLE baz( 
    pkey   SERIAL PRIMARY KEY, 
    bar_fk   VARCHAR(256) NOT NULL REFERENCES bar(name), 
    name   VARCHAR(256) 
); 

COMMIT; 

運行上面的代碼提供了以下錯誤,這沒有任何意義對我來說,任何人都可以解釋爲什麼這個錯誤出現。我使用的是Postgres 9.1

NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "foo_pkey" for table "foo" 
NOTICE: CREATE TABLE will create implicit sequence "bar_pkey_seq" for serial column "bar.pkey" 
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "bar_pkey" for table "bar" 
NOTICE: CREATE TABLE/UNIQUE will create implicit index "bar_foo_fk_name_key" for table "bar" 
NOTICE: CREATE TABLE will create implicit sequence "baz_pkey_seq" for serial column "baz.pkey" 
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "baz_pkey" for table "baz" 
ERROR: there is no unique constraint matching given keys for referenced table "bar" 


********** Error ********** 

ERROR: there is no unique constraint matching given keys for referenced table "bar" 
SQL state: 42830 

回答

63

這是因爲bar表中的name列沒有UNIQUE約束。

所以,想象一下你對bar表包含名稱'ams'和你bar_fk插入上baz一排'ams',該行對bar會是指因爲有兩行匹配2行?

42

PostgreSQL中所有的外鍵必須在父表中引用唯一鍵,所以在你bar表,你必須有一個unique (name)指數。

參見http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK特別:

Finally, we should mention that a foreign key must reference columns that either are a primary key or form a unique constraint.

重點煤礦。

+7

爲什麼不將聲明的PK視爲唯一約束?它不像你可以有一個非唯一的PK ... – amphibient 2016-09-07 18:14:35

+0

它必須在它「指向」的表上是唯一的,因爲如果它不是,數據庫引擎將無法知道你實際上指的是哪一行。 – 2016-09-07 18:15:48

4

當你做UNIQUE爲你做了那麼你的定義是什麼表級別的約束有點像一個複合主鍵看ddl constraints,這裏是一個提取

"This specifies that the *combination* of values in the indicated columns is unique across the whole table, though any one of the columns need not be (and ordinarily isn't) unique." 

這意味着,無論是現場可能可能有一個非唯一值,前提是組合是唯一的,這與您的外鍵約束不匹配。

最有可能您希望限制在列級別。然後將它們定義爲表級約束,'UNIQUE'附加到列定義的末尾,如name VARCHAR(60) NOT NULL UNIQUE或爲每個字段指定單獨的表級約束。

+0

在我的情況下列級約束不起作用我真的應該定義一個複合主鍵,但我退出了它,因爲它映射到JPA其有點痛:) – ams 2012-08-15 09:15:35

1

您應該將name列作爲唯一約束。這裏是一個代碼3行改變你的問題

1.首先找到主鍵約束通過輸入這個代碼

\ d table_name的

你這個樣子,在底部 「some_constraint」 PRIMARY KEY,B樹(列)

2.drop約束:

ALTER TABLE TABLE_NAME DROP約束some_constraint

3。使用現有的主鍵列添加新的主鍵列:

ALTER TABLE table_name ADD CONSTRAINT some_constraint PRIMARY KEY(COLUMN_NAME1,COLUMN_NAME2);

這就是全部。

相關問題