Usando la regla para insertar en la tabla secundaria Secuencia Auto-Incrementos

StackOverflow https://stackoverflow.com/questions/2253357

  •  20-09-2019
  •  | 
  •  

Pregunta

Para agregar automáticamente una columna en una segunda tabla para empatar el partido a la primera tabla a través de un índice único, tengo una regla como la siguiente:

CREATE OR REPLACE RULE auto_insert AS ON INSERT TO user DO ALSO
INSERT INTO lastlogin (id) VALUES (NEW.userid);

Esto funciona bien si user.userid es un número entero. Sin embargo, si se trata de una secuencia (por ejemplo, tipo serial o BIGSERIAL ), lo que se inserta en la tabla lastlogin es la siguiente secuencia ID. Por lo que este comando:

INSERT INTO user (username) VALUES ('john');

insertaría columna [1, 'john', ...] en usuario pero en columna [2, ...] en lastlogin . Los siguientes 2 soluciones funcionan excepto que el segundo consume el doble de los seriales ya que la secuencia es todavía de incremento automático:

CREATE OR REPLACE RULE auto_insert AS ON INSERT TO user DO ALSO
INSERT INTO lastlogin (id) VALUES (lastval());

CREATE OR REPLACE RULE auto_insert AS ON INSERT TO user DO ALSO
INSERT INTO lastlogin (id) VALUES (NEW.userid-1);

Desafortunadamente, las soluciones no funcionan si estoy insertar varias filas:

INSERT INTO user (username) VALUES ('john'), ('mary');

La primera solución sería utilizar el mismo ID, y la segunda solución consiste en todo tipo de metedura de pata.

¿Es posible hacerlo a través de reglas de PostgreSQL o debería simplemente hacer la segunda inserción en lastlogin a mí mismo o utilizar un disparador fila? En realidad, creo que la fila de gatillo haría también autoincrementación la secuencia cuando accedo a NEW.userid .

¿Fue útil?

Solución

Forget reglas por completo. Son mal .

Los desencadenantes son mucho mejores para usted. Y en el 99% de los casos cuando alguien piensa que necesita una regla. Prueba esto:

create table users (
  userid serial primary key,
  username text
);

create table lastlogin (
  userid int primary key references users(userid),
  lastlogin_time timestamp with time zone
);

create or replace function lastlogin_create_id() returns trigger as $$
  begin
    insert into lastlogin (userid) values (NEW.userid);
    return NEW;
  end;
$$
language plpgsql volatile;

create trigger lastlogin_create_id
  after insert on users for each row execute procedure lastlogin_create_id();

A continuación:

insert into users (username) values ('foo'),('bar');

select * from users;
 userid | username 
--------+----------
      1 | foo
      2 | bar
(2 rows)
select * from lastlogin;
 userid | lastlogin_time 
--------+----------------
      1 | 
      2 | 
(2 rows)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top