检查行是否已存在,如果存在,则告诉引用的表 id

发布于 2024-08-25 01:59:40 字数 1118 浏览 4 评论 0原文

假设我有一本表格杂志:

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

现在,如果一行尚不存在,则只能将其插入到“杂志”中。但是,如果存在,表“issue”需要获取已存在的行的“magazine_id”才能建立引用。

我该怎么做?

提前谢谢!

Let's assume I have a table magazine:

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

And another table issue:

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

Current INSERTS:

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

Now a row should only be inserted into 'magazine', if it does not already exist. However if it exists, the table 'issue' needs to get the 'magazine_id' of the row that already exists in order to establish the reference.

How can i do this?

Thx in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

灯下孤影 2024-09-01 01:59:40

您如何知道杂志是否已在 magazine 表中? issn 列是否定义一本杂志?如果是,那么它应该是主键,或者至少是唯一的。

最简单的方法是检查客户端应用程序中是否存在杂志,如下所示(以伪代码形式):

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 函数,并且只需 <代码>选择 insert_issue(?, ?, ?, ?, ?, ?)。

How do you know if a magazine is already in magazine table? Does issn column define a magazine? If yes then it should be a primary key, or at least unique.

The easiest way would be to do a check for magazine existence in your client application, like this (in 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";
    }
}

If you just have to do this in one query then you can implement this pseudocode as pl/pgsql function in database and just select insert_issue(?, ?, ?, ?, ?, ?).

舞袖。长 2024-09-01 01:59:40

如果您使用的是 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's FTW!

If you are on PostgreSQL 9.1 or higher you can do something like:

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's FTW!

池予 2024-09-01 01:59:40

我不确定你是否可以用 SQL 来做到这一点。我知道Oracle可以用于触发器,但我不认为SQL可以。如果我错了,有人纠正我。

I'm not sure that if you can do this with SQL. I know that Oracle can be used for triggers, but i don't think SQL is able to. Someone correct me if I'm wrong.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文