存储过程,如果存在返回ID或插入并返回ID

时间:2019-04-16 18:38:57

标签: sql stored-procedures db2

我有一个非常简单的DB2存储过程,我在其中存储参数字符串并将其插入到表中,效果很好,但我确实需要对其进行扩展。当前看起来像这样:

    IN_TAG_DATA


    P1 : BEGIN ATOMIC

    INSERT INTO SCHEMA.TAGS(TAG_DATA)
    VALUES(IN_TAG_DATA);

    END P1

我现在需要做的是放在相同的字符串参数中,但是基于该参数,我需要检查名称是否已经存在,如果存在,请选择/返回其ID。如果不存在,则需要插入它,然后返回创建的ID。

如何更改此设置以在此处获得适当的功能?

    IN_TAG_DATA
    OUT_TAG_ID

    P1 : BEGIN ATOMIC

    DECLARE V_TAG_ID INTEGER;

    SELECT CAST(NEXT VALUE FOR SCHEMA . TAG_ID_SEQ AS INTEGER)
    INTO V_TAG_ID
    FROM SYSIBM . SYSDUMMY1;

    /*
    IF EXISTS BASED ON IN_TAG_DATA, GET ID ELSE INSERT AND RETURN created ID
    */


    SET OUT_TAG_ID
    END P1

2 个答案:

答案 0 :(得分:1)

--#SET TERMINATOR @
CREATE TABLE TAGS(TAG_ID INT NOT NULL GENERATED ALWAYS AS IDENTITY, TAG_DATA VARCHAR(20) NOT NULL) IN USERSPACE1@

CREATE OR REPLACE PROCEDURE TAGS(P_TAG_DATA VARCHAR(20), OUT P_TAG_ID INT)
BEGIN

FOR C1 AS 
  WITH E (TAG_ID) AS (
    SELECT TAG_ID
    FROM TAGS
    WHERE TAG_DATA=P_TAG_DATA
  )
  , I AS (
    SELECT TAG_ID
    FROM NEW TABLE (
      INSERT INTO TAGS (TAG_DATA) 
      SELECT P_TAG_DATA FROM TABLE(VALUES 1)
      WHERE NOT EXISTS (SELECT 1 FROM E)
    )
  )
  SELECT COALESCE(E.TAG_ID, I.TAG_ID) TAG_ID
  FROM I FULL JOIN E ON 1=1

  DO
    SET P_TAG_ID = C1.TAG_ID;
  END FOR;

END@

有点复杂,但是...
可以通过此单个语句执行所有需要的操作。 E包含一个TAG_ID值(如果存在)。我们仅在不存在新行时才插入它,并使用SELECT FROM data-change-table-reference检索插入的TAG_ID。最后,我们加入现有行并插入一个。其中只有一个存在,而我们得到了TAG_IDs其中之一。

如果您在LUB 11.1的Db2上,则不需要FOR循环-SELECT INTO语句支持CTE,因此可以仅将单个语句与SELECT COALESCE(E.TAG_ID, I.TAG_ID) INTO P_TAG_ID一起使用而没有循环。以前的Db2版本不支持它,因此,我们必须使用FOR循环来检索单个值。

答案 1 :(得分:0)

IN_TAG_DATA
OUT_TAG_ID

P1 : BEGIN ATOMIC

Check if the TAG ID exists in the database

IF EXISTS (SELECT TAG_ID FROM SYSIBM . SYSDUMMY1 WHERE xx = TAG_DATA) 
THEN

Return TAG ID

BEGIN
SET OUT_TAG_ID = TAG_ID
END;
ELSE

insert it and then return the created ID

BEGIN
INSERT INTO SCHEMA.TAGS(TAG_DATA)
VALUES(IN_TAG_DATA)
SET OUT_TAG_ID = TAG_ID
END;
END IF;

END P1