3

シーケンスを参照する外部キーを作成するときに問題が発生しました。以下のコード例を参照してください。
しかし、テーブルを作成すると、次のエラーが表示されます。
「詳細: キー列 "product" と "id" は互換性のない型です: integer と ownseq」
製品列にさまざまなデータ型 (smallint、bigint など) を既に試しましたが、どれも受け入れられません。

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

3 に答える 3

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定義されていることです。これは、疑似タイプを使用してシーケンスを作成した場合に発生することです。integerownseqSERIAL

于 2013-02-28T14:17:29.703 に答える
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 では実際には非常に強力ですが、予想外のコーナーがたくさんあります (たとえば、null ではなく、ネストされたデータ型ではチェック制約が期待どおりに機能しません)。通常、ネストされたデータ型はお勧めしませんが、PostgreSQL がこれを実行できること、および SQL コマンドを警告なしで喜んで受け入れることを知っておくことは価値があります。

于 2013-02-28T15:31:26.950 に答える
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.

お役に立てれば。

于 2013-02-28T14:24:34.593 に答える