sql >> データベース >  >> RDS >> PostgreSQL

別の列に基づくPostgreSQLシーケンス

    問題ない! thingsという2つのテーブルを作成します およびstuffstuff 質問で説明する表とthingsになります それが参照するものです:

    CREATE TABLE things (
        id serial primary key,
        name text
    );
    
    CREATE TABLE stuff (
        id integer references things,
        seq integer NOT NULL,
        notes text,
        primary key (id, seq)
    );
    

    次に、thingsを設定します 行が作成されるたびに新しいシーケンスを作成するトリガーを使用します:

    CREATE FUNCTION make_thing_seq() RETURNS trigger
        LANGUAGE plpgsql
        AS $$
    begin
      execute format('create sequence thing_seq_%s', NEW.id);
      return NEW;
    end
    $$;
    
    CREATE TRIGGER make_thing_seq AFTER INSERT ON things FOR EACH ROW EXECUTE PROCEDURE make_thing_seq();
    

    これで、thing_seq_1になります。 、thing_seq_2 、などなど...

    stuffの別のトリガー 毎回正しいシーケンスを使用するように:

    CREATE FUNCTION fill_in_stuff_seq() RETURNS trigger
        LANGUAGE plpgsql
        AS $$
    begin
      NEW.seq := nextval('thing_seq_' || NEW.id);
      RETURN NEW;
    end
    $$;
    
    CREATE TRIGGER fill_in_stuff_seq BEFORE INSERT ON stuff FOR EACH ROW EXECUTE PROCEDURE fill_in_stuff_seq();
    

    これにより、行がstuffに入るときに確実になります 、id 列は、nextvalを呼び出すための正しいシーケンスを見つけるために使用されます オン。

    これがデモンストレーションです:

    test=# insert into things (name) values ('Joe');
    INSERT 0 1
    test=# insert into things (name) values ('Bob');
    INSERT 0 1
    test=# select * from things;
     id | name
    ----+------
      1 | Joe
      2 | Bob
    (2 rows)
    
    test=# \d
                  List of relations
     Schema |     Name      |   Type   |  Owner
    --------+---------------+----------+----------
     public | stuff         | table    | jkominek
     public | thing_seq_1   | sequence | jkominek
     public | thing_seq_2   | sequence | jkominek
     public | things        | table    | jkominek
     public | things_id_seq | sequence | jkominek
    (5 rows)
    
    test=# insert into stuff (id, notes) values (1, 'Keychain');
    INSERT 0 1
    test=# insert into stuff (id, notes) values (1, 'Pet goat');
    INSERT 0 1
    test=# insert into stuff (id, notes) values (2, 'Family photo');
    INSERT 0 1
    test=# insert into stuff (id, notes) values (1, 'Redundant lawnmower');
    INSERT 0 1
    test=# select * from stuff;
     id | seq |        notes
    ----+-----+---------------------
      1 |   1 | Keychain
      1 |   2 | Pet goat
      2 |   1 | Family photo
      1 |   3 | Redundant lawnmower
    (4 rows)
    
    test=#
    


    1. MySQLドロップインデックス

    2. テーブルのすべての値をSQLの別のテーブルに挿入します

    3. MariaDBでのDATEDIFF()のしくみ

    4. SQLServerのデータベースからすべてのトリガーを削除または削除する方法