2010-03-12 4 views
1

Supposons que j'ai une revue de table:Vérifiez si la ligne existe déjà, le cas échéant dire la table référencée l'id

CREATE TABLE magazine 
(
    magazine_id integer NOT NULL DEFAULT nextval(('public.magazine_magazine_id_seq'::text)::regclass), 
    longname character varying(1000), 
    shortname character varying(200), 
    issn character varying(9), 
    CONSTRAINT pk_magazine PRIMARY KEY (magazine_id) 
); 

Et une autre question de table:

CREATE TABLE issue 
(
    issue_id integer NOT NULL DEFAULT nextval(('public.issue_issue_id_seq'::text)::regclass), 
    number integer, 
    year integer, 
    volume integer, 
    fk_magazine_id integer, 
    CONSTRAINT pk_issue PRIMARY KEY (issue_id), 
    CONSTRAINT fk_magazine_id FOREIGN KEY (fk_magazine_id) 
     REFERENCES magazine (magazine_id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
); 

INSERTS actuel:

INSERT INTO magazine (longname,shotname,issn) 
VALUES ('a long name','ee','1111-2222'); 

INSERT INTO issue (fk_magazine_id,number,year,volume) 
VALUES (currval('magazine_magazine_id_seq'),'8','1982','6'); 

Maintenant, une ligne ne doit être insérée dans «magazine», si elle n'existe pas déjà. Cependant, si elle existe, la table 'issue' doit obtenir le 'magazine_id' de la ligne qui existe déjà afin d'établir la référence.

Comment puis-je faire cela?

Merci d'avance!

Répondre

-1

Je ne suis pas sûr que si vous pouvez le faire avec SQL. Je sais que Oracle peut être utilisé pour les déclencheurs, mais je ne pense pas que SQL est capable de le faire. Quelqu'un me corrige si je me trompe.

+0

Je ne sais même pas quoi dire de cette "réponse". –

1

Comment savoir si un magasin est déjà dans le tableau magazine? La colonne issn définit-elle un magasin? Si oui, il devrait s'agir d'une clé primaire, ou au moins unique.

La meilleure façon serait de faire un chèque pour l'existence du magazine dans votre application cliente, comme celui-ci (en pseudocode):

function insert_issue(longname, shotname, issn, number,year,volume) { 
    /* extensive comments for newbies */ 
    start_transaction(); 
    q_get_magazine_id = prepare_query(
     'select magazine_id from magazine where issn=?' 
    ); 
    magazine_id = execute_query(q_get_magazine_id, issn); 
    /* if magazine_id is null now then there’s no magazine with this issn */ 
    /* and we have to add it */ 
    if (magazine_id == NULL) { 
     q_insert_magazine = prepare_query(
     'insert into magazine (longname, shotname, issn) 
      values (?,?,?) returning magazine_id' 
    ); 
     magazine_id = execute_query(q_insert_magazine, longname, shortname, issn); 
     /* we have tried to add a new magazine; */ 
     /* if we failed (magazine_id==NULL) then somebody else just added it */ 
     if (magazine_id == NULL) { 
     /* other, parerelly connected client just inserted this magazine, */ 
     /* this is unlikely but possible */ 
     rollback(); 
     start_transaction(); 
     magazine_id = execute_query(q_get_magazine_id, issn); 
     } 
    } 
    /* now magazine_id is an id of magazine, */ 
    /* added if it was not in a database before, new otherwise */ 
    q_insert_issue = prepare_query(
     'insert into issue (fk_magazine_id,number,year,volume) 
     values (?,?,?,?)' 
    ); 
    execute_query(q_insert_issue, magazine_id, number, year, volume); 
    /* we have inserted a new issue referencing old, */ 
    /* or if it was needed new, magazine */ 
    if (! commit()) { 
     rollback(); 
     raise "Unable to insert an issue"; 
    } 
} 

Si vous avez juste à le faire dans une requête, vous pouvez mettre en œuvre cette pseudocode comme fonction pl/pgsql dans la base de données et juste select insert_issue(?, ?, ?, ?, ?, ?).

+0

merci pour votre réponse. comment je sais si un magazine est déjà dans la table du magazine? Je ne sais pas comment faire cela mais je suppose que vous devrez vérifier si la ligne que vous êtes sur le point d'insérer existe déjà, peut-être avec une requête WHERE EXISTS. le magazine_id devrait définir un magazine, au moins je l'ai prévu de cette façon. – flhe

+0

Je suis confus. S'il vous plaît, répondez à quelques questions: 1. Peut-il y avoir deux magazines avec le même ISSN? 2. Peut-il y avoir deux magasins avec le même nom long? 3. Peut-il y avoir deux magazines avec le même nom abrégé? – Tometzky

+0

Désolé de vous avoir confus. 1. Non, un magazine a un ISSN unique. 2. Non, les magazines sont uniques. 3. No. Le problème est qu'il peut arriver, que j'insère un jeu de données avec le magazine xy et magazine_id = 1. Plus tard, il pourrait arriver que le même magazine xy soit inséré dans la table sous la forme de l'ensemble de données 400. Donc, le magazine xy aurait aussi magazine_id = 400 ce qui est mauvais. Le magazine xy devrait s'en tenir à magazine_id = 1 – flhe

0

Si vous êtes sur PostgreSQL 9.1 ou supérieur, vous pouvez faire quelque chose comme:

WITH ref_key (id) AS (
    WITH ins (id) AS (
     INSERT INTO magazine (longname,shotname,issn) 
     VALUES ('a long name','ee','1111-2222') 
     RETURNING id 
    ) 
    SELECT id 
     FROM magazine 
     LEFT JOIN ins USING id 
    WHERE issn = '1111-2222' 
) 
INSERT INTO INTO issue (fk_magazine_id,number,year,volume) 
SELECT id,'8','1982','6' 
    FROM ref_key; 

inscriptible CTE FTW!

Questions connexes