2010-03-12 5 views
1

Давайте предположим, что у меня есть таблицы журнала:Проверьте строка уже существует, если так сказать ссылочной таблицы идентификатор

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) 
); 

И еще один вопрос таблицы:

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 
); 

Текущие Вставки:

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'); 

Теперь строка должна быть вставлена ​​в «журнал», если она еще не существует. Однако, если он существует, в таблице «проблема» необходимо получить «журнал_ид» строки, которая уже существует, чтобы установить ссылку.

Как я могу это сделать?

Thx заранее!

ответ

-1

Я не уверен, что если вы можете сделать это с помощью SQL. Я знаю, что Oracle можно использовать для триггеров, но я не думаю, что SQL может это сделать. Кто-то исправит меня, если я ошибаюсь.

+0

Я даже не уверен, что сказать об этом «ответе». –

1

Откуда вы знаете, если журнал уже находится в таблице magazine? Столбец issn определяет журнал? Если да, то это должен быть первичный ключ или не менее unique.

Проще всего было бы сделать чек на журнал существования в клиентском приложении, как это (в псевдокоде):

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"; 
    } 
} 

Если вы просто должны сделать это в одном запросе, то вы можете осуществить это псевдокод как функция pl/pgsql в базе данных и только select insert_issue(?, ?, ?, ?, ?, ?).

+0

спасибо за ваш ответ. как я знаю, если журнал уже в журнальном столе? Я не знаю, как это сделать, но я думаю, вам нужно будет проверить, существует ли строка, которую вы собираетесь вставить, уже существует, возможно, с запросом WHERE EXISTS. журнал_ид должен определить журнал, по крайней мере, я планировал его таким образом. – flhe

+0

Я в замешательстве. Ответьте на несколько вопросов: 1. Могут ли быть два журнала с одним и тем же ISSN? 2. Могут ли быть два магазина с тем же самым длинным именем? 3. Могут ли быть два журнала с одним и тем же именем? – Tometzky

+0

Извините, что вы смутили вас. 1. Нет, журнал имеет уникальный ISSN. 2. Нет, журналы уникальны. 3. № Проблема в том, что может случиться так, что я вставляю набор данных в журнал xy и magazine_id = 1. Затем может случиться так, что абсолютный же журнал xy будет вставлен в таблицу в качестве набора данных 400. Таким образом, журнал xy также имел бы journal_id = 400, что плохо. Журнал xy должен придерживаться journal_id = 1 – flhe

0

Если вы на PostgreSQL 9.1 или выше, вы можете сделать что-то вроде:

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; 

Writeable CTE-х FTW!

Смежные вопросы