sql-server - T-SQL 在 BEGIN CATCH 中插入
问题描述
在此先感谢您的帮助。
我想要实现的是处理违反 FK(市政代码)的约束,在这种情况下,我想将记录插入到辐射表中。
在这段代码中,select 的结果可以为 null,因此会抛出异常,因为我在目标上有一个 not null 子句。
TARGET.MUNICIPALITYCODE = (SELECT m.MUNICIPALITYCODE FROM MUNICIPALITY m WHERE SOURCE.MUNICIPALITYCODE = m.MUNICIPALITYCODE)
我希望能够处理 BEGIN CATCH 块上的异常并将我在 SOURCE 上使用的值插入到我选择的表中。
有谁知道这是否可能?
CREATE PROCEDURE upsertStagingToStreet
AS
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRY
BEGIN TRAN
MERGE STREET AS TARGET
USING STREET_STAGING AS SOURCE
ON (TARGET.correlationkey = SOURCE.correlationkey)
WHEN MATCHED
THEN UPDATE SET TARGET.Qty = SOURCE.Qty,
TARGET.MUNICIPALITYCODE = (SELECT m.MUNICIPALITYCODE FROM MUNICIPALITY m WHERE SOURCE.MUNICIPALITYCODE = m.MUNICIPALITYCODE)
WHEN NOT MATCHED BY TARGET
THEN INSERT (MUNICIPALITYCODE, STREENAME,STREECODE) VALUE ((SELECT m.MUNICIPALITYCODE FROM MUNICIPALITY m WHERE SOURCE.MUNICIPALITYCODE = m.MUNICIPALITYCODE),SOURCE.STREETCODE,SOURCE.STREETCODE)
COMMIT
END TRY
begin catch
# I'm not able to figure this part out.
INSERT INTO STREET_FALLOUT (MUNICIPALITYCODE, STREENAME,STREECODE,ERRORREASON) VALUES (SOURCE.MUNICIPALITYCODE,STREETNAME,STREETCODE,ERROR_MESSAGE())
end catch
解决方案
你正在接近这个错误。无法插入某些行并捕获其他行的错误。
相反,只需查询不匹配的行,并仅合并匹配的行。
- 请注意缺少错误处理,并包含
XACT_ABORT ON
. 这是正确的方法,因为所有错误都会导致事务回滚。 - 请注意,
SOURCE
合并中的表与 预联接MUNICIPALITY
,因此只能出现匹配的行。 - 一个
MERGE
语句必须有一个分号终止符,无论如何这是一个好习惯。
CREATE PROCEDURE upsertStagingToStreet
AS
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SET XACT_ABORT, NOCOUNT ON;
BEGIN TRAN
INSERT INTO STREET_FALLOUT
(MUNICIPALITYCODE, STREENAME, STREECODE, ERRORREASON)
SELECT
SOURCE.MUNICIPALITYCODE,
SOURCE.STREETCODE,
SOURCE.STREETCODE,
'Missing MUNICIPALITYCODE'
FROM STREET_STAGING AS SOURCE
WHERE NOT EXISTS (SELECT 1
FROM MUNICIPALITY m
WHERE SOURCE.MUNICIPALITYCODE = m.MUNICIPALITYCODE
);
WITH SOURCE AS (
SELECT SOURCE.*
FROM STREET_STAGING AS SOURCE
JOIN MUNICIPALITY m ON SOURCE.MUNICIPALITYCODE = m.MUNICIPALITYCODE
)
MERGE STREET AS TARGET
USING SOURCE
ON (TARGET.correlationkey = SOURCE.correlationkey)
WHEN MATCHED THEN
UPDATE SET
Qty = SOURCE.Qty,
MUNICIPALITYCODE = SOURCE.MUNICIPALITYCODE
WHEN NOT MATCHED BY TARGET THEN
INSERT (MUNICIPALITYCODE, STREENAME, STREECODE)
VALUES (SOURCE.MUNICIPALITYCODE, SOURCE.STREETCODE, SOURCE.STREETCODE)
;
COMMIT;
GO
推荐阅读
- node.js - mongodb 多文档更新的最佳实践(无事务)
- angular - 无法读取未定义读取json中现有数组的属性
- python-3.x - Geoalchemy2 在给定坐标内找到一定距离内的位置
- swift - UIint64 数据溢出问题
- javascript - query.startAt 数据库规则权限被拒绝
- django - 无效的 pk(模型对象)不存在 - Django REST 框架
- javascript - 如何更改 HTML Canvas 中每个数组元素的不透明度
- node.js - 使用创建反应应用程序的 npm-start 上未处理的错误
- c - 如何捕获 SIGINT 并让它只杀死 C 中的前台进程?
- markdown - 带有 Pandoc 和 Markdown 的 Beamer 演示文稿 - 波斯语字符无法正确显示