3

postgresデータベースにいくつかのテーブルがあり、そのうちのいくつかは相互に継承しています。

例えば:

CREATE TABLE parent_table(parent_table_id SERIAL PRIMARY KEY, 
       my_col1 VARCHAR(16) NOT NULL, 
       my_timestamp TIMESTAMP WITH TIME ZONE NOT NULL);
CREATE TABLE child_table() INHERITS (parent_table);
CREATE TABLE step_child_table() INHERITS (parent_table);

parent_tableで挿入を実行し、データを実際に子テーブルまたはstep_childテーブルに入れる必要があるかどうかを判断するトリガーがあります。

例えば:

CREATE OR REPLACE FUNCTION my_parent_trigger() RETURNS TRIGGER AS $$
BEGIN
  IF (NEW.my_col1 > 100) THEN
      INSERT INTO child_table(my_col1, my_timestamp) VALUES (NEW.my_col1, NEW.my_timestamp);
  ELSE
      INSERT INTO step_child_table(my_col1, my_timestamp) VALUES (NEW.my_col1, NEW.my_timestamp);
  END IF;
  RETURN NULL;
END;
$$
CREATE TRIGGER my_trigger BEFORE INSERT ON parent_table FOR EACH ROW EXECUTE PROCEDURE my_parent_trigger();

問題は、インデックスが2ずつ増加していることです。データを挿入し、parent_tableで選択を行うと、インデックスが2から始まり、4、6、8、10、...に進むことがわかります。 child_tableでselectを実行すると、インデックス(2、8、および10など)が表示され、残りは他のテーブルに表示されます。

どうしてこれなの?それを止める方法はありますか?トリガーは挿入前に設定されているので、シリアルが2回インクリメントされる理由がわかりません。

それは重要ですか?

前もって感謝します。

4

2 に答える 2

2

このコードでシーケンスを1つだけインクリメントしても、一般に、シーケンスから初期化された列にギャップがないことを期待することはできませんbegin; insert into foo (...); abort。トランザクションが中止されても、シーケンスはインクリメントされたままになります。

A. Elein Mustainは、ギャップのないシーケンスを作成する方法を示しています。

于 2010-02-17T22:50:20.973 に答える
2

子テーブルに挿入するときは、parent_table_id列を含める必要があると思います。

現在、シーケンスは親挿入に対して1回進められ、そこからの値がNEWの関数に渡されます。次に、それを破棄し、子テーブルに挿入するときに新しいテーブルを生成するようにシステムに要求します。

したがって、列のリストにparent_table_idを含めて、NEW.parent_table_idの値を挿入してみてください。

于 2010-02-18T09:32:13.397 に答える