sql - 存储过程,如果存在则返回 ID 或插入并返回 ID
问题描述
我有一个非常简单的 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
解决方案
--#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@
A little bit complicated, but...
All actions needed can be performed by this single statement. E
contains a TAG_ID
value if it exists. We insert a new row only if it doesn't exist, and retrieve inserted TAG_ID
using SELECT FROM data-change-table-reference. Finally, we join existing row and inserted one. Only one of them exists, and we get one of these TAG_IDs
.
If you are at Db2 for LUW 11.1, then FOR
loop is not needed - the SELECT INTO
statement supports CTE, so one can use just a single statement with SELECT COALESCE(E.TAG_ID, I.TAG_ID) INTO P_TAG_ID
without a loop. Prior Db2 versions don't support it, so, we have to use FOR
loop just to retrieve a single value.
推荐阅读
- html - 在 Netlify 上部署后,Roboto 字体在 Safari 或移动浏览器中不起作用
- python - setdefault 附加到每个键
- css - 使用 chrome 代码检查器时,我无法访问最新的样式表
- swift - 您如何进行实时数据库查询来检查用户的时间戳是否在今天?
- laravel - 在 dockerized Laravel 应用程序中返回 404 错误的图像。存储在卷中的图像
- javascript - 图表未呈现
- xslt-2.0 - XSLT 的严格编译,但不验证应用程序上的输入 XML
- javascript - 如何使用 Joi 验证具有未知键的对象并检查值是否为标量类型?
- bash - 来自守护进程的错误响应:OCI 运行时创建失败:container_linux.go:349:启动容器进程导致“exec:\”/bin/bash\”
- reactjs - 简单的反应状态不会在第一次请求时改变