2013-02-28 42 views
3

創建引用序列的外鍵時遇到問題,請參閱下面的代碼示例。
但在創建表我收到以下錯誤。
「詳細信息:鍵列」產品「和」ID「是不兼容的類型:整數和ownseq」
我已經嘗試了產品列的不同數據類型(如smallint,bigint),但都不接受。對序列列的引用(postgresql)

CREATE SEQUENCE ownseq INCREMENET BY 1 MINVALUE 100 MAXVALUE 99999; 
CREATE TABLE products ( 
id ownseq PRIMARY KEY, 
...); 

CREATE TABLE basket (
basket_id SERIAL PRIMARY KEY, 
product INTEGER FOREIGN KEY REFERENCES products(id)); 

回答

4
CREATE SEQUENCE ownseq INCREMENT BY 1 MINVALUE 100 MAXVALUE 99999; 
CREATE TABLE products ( 
    id integer PRIMARY KEY default nextval('ownseq'), 
    ... 
); 
alter sequence ownseq owned by products.id; 

關鍵的變化是id被定義爲integer,而不是作爲ownseq。如果您使用SERIAL僞類型創建序列,將會發生這種情況。

2

嘗試

CREATE TABLE products ( 
    id INTEGER DEFAULT nextval(('ownseq'::text)::regclass) NOT NULL PRIMARY KEY, 
    ...); 

或不創建序列ownseq,讓Postgres的爲你做它:

CREATE TABLE products (
    id SERIAL NOT NULL PRIMARY KEY 
    ...); 

在上述情況下的流程的Postgres的名字創建要products_id_seq

希望這會有所幫助。

+0

'主鍵'意味着'非空',所以後者是沒有必要的。 – 2013-02-28 14:29:04

+0

是的,根據版本的不同,轉換爲'regclass'是必要的。 – 2013-02-28 14:29:43

+0

此語法是否在「create table」語句內創建序列? 是否可以像原始陳述一樣設置最小值和最大值? – 2013-12-03 16:38:06

2

PostgreSQL功能強大,您剛剛被高級功能所咬。

你的DDL是相當有效的,但不是你想象的那樣。

一個序列可以被認爲是一個額外事務的簡單表,用於爲某些列生成下一個值。

你的意思辦

你的意思是有id字段定義。因此,按照對方的回答:

id integer PRIMARY KEY default nextval('ownseq'), 

你做了什麼

你做了什麼實際上是爲你的表定義一個嵌套的數據結構。假設我創建了一個測試序列:

CREATE SEQUENCE testseq; 

然後假設我\d testseq在PG 9.1,我得到:

  Sequence "public.testseq" 
    Column  | Type |  Value   
---------------+---------+--------------------- 
sequence_name | name | testseq 
last_value | bigint | 1 
start_value | bigint | 1 
increment_by | bigint | 1 
max_value  | bigint | 9223372036854775807 
min_value  | bigint | 1 
cache_value | bigint | 1 
log_cnt  | bigint | 0 
is_cycled  | boolean | f 
is_called  | boolean | f 

這是所使用的序列類型的定義。

現在假設我:

create table seqtest (test testseq, id serial); 

我可以插入到它:

INSERT INTO seqtest (id, test) values (default, '("testseq",3,4,1,133445,1,1,0,f,f)'); 

然後我就可以從中選擇:

select * from seqtest; 
       test    | id 
----------------------------------+---- 
(testseq,3,4,1,133445,1,1,0,f,f) | 2 

而且我還可以擴大測試:

SELECT (test).* from seqtest; 

select (test).* from seqtest; 
sequence_name | last_value | start_value | increment_by | max_value | min_value 
| cache_value | log_cnt | is_cycled | is_called 
---------------+------------+-------------+--------------+-----------+---------- 
-+-------------+---------+-----------+----------- 
       |   |    |    |   |   
|    |   |   | 
testseq  |   3 |   4 |   1 | 133445 |   1 
|   1 |  0 | f   | f 
(2 rows) 

這種事情在PostgreSQL中實際上非常強大,但充滿了意想不到的角落(例如,非嵌套數據類型不爲空和檢查約束無法正常工作)。我通常不推薦嵌套的數據類型,但值得知道的是PostgreSQL可以做到這一點,並且很樂意接受SQL命令來執行它,而不會發出警告。