2013-02-28 4 views
3

У меня возникла проблема при создании внешнего ключа, ссылающегося на последовательность, см. Пример кода ниже.
Но при создании таблиц я получаю следующую ошибку.
«Подробно: ключевые столбцы« продукт »и« id »являются несовместимыми типами: integer и 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

'первичный ключ' подразумевает' не null', поэтому последнее не нужно. –

+0

И да, в зависимости от версии необходим листинг для 'regclass'. –

+0

Этот синтаксис создает последовательность в инструкции «create table»? И можно ли установить минимальное значение и максимальное значение, например, исходное утверждение? –

2

PostgreSQL является мощным, и вы только что были укушены расширенной функцией.

Ваш DDL вполне действителен, но совсем не так, как вы думаете.

Последовательность можно рассматривать как дополнительную транзакционную простую таблицу, используемую для генерации следующих значений для некоторых столбцов.

Что вы имели в виду сделать

Вы имели в виду, чтобы иметь поле идентификатор определяется таким образом, в соответствии с другой ответ:

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

Что вы сделали

Что вы сделали фактически определял вложенную структуру данных для вашей таблицы. Предположим, я создаю тестовую последовательность:

CREATE SEQUENCE testseq; 

Тогда предположим, что я \d testseq на Рв 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, чтобы сделать это без предупреждения.

Смежные вопросы