You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建存储过程时‘with’关键字附近语法错误的问题求助

解决MERGE语句中WITH关键字附近的语法错误问题

看起来你遇到的语法错误主要来自两个核心问题:OPENJSON的WITH子句定义不完整,以及MERGE语句的核心逻辑结构缺失。我帮你梳理并修正了代码,同时详细解释问题根源:

错误根源分析

  1. 截断的字段类型声明:你提供的代码里Memo V...明显是被截断了,SQL Server无法识别不完整的数据类型定义,这直接触发了WITH关键字附近的语法报错。
  2. 不完整的MERGE结构:MERGE语句必须包含匹配条件、至少一个操作分支(UPDATE/INSERT/DELETE),你的代码只写到了AS Source就中断了,缺少核心的逻辑分支,这也是语法错误的重要原因。

修正后的完整存储过程

CREATE PROCEDURE usp_PaymentRecommendationsInsertUpdate 
    @PaymentRecommendationsJson NVARCHAR(MAX)
AS
BEGIN
    SET NOCOUNT ON; -- 抑制影响行数消息,提升执行体验

    MERGE INTO PaymentRecommendations AS Target
    USING (
        SELECT 
            ClaimId, 
            CoverageTypeId, 
            Payee, 
            IndemnityPmtRequestAmnt, 
            ExpensePaymentRequestAmnt, 
            RequestDate, 
            Memo, 
            CheckNumber, 
            IssueDate, 
            CreatedOn, 
            CreatedBy, 
            ModifiedOn, 
            ModifiedBy
        FROM OPENJSON(@PaymentRecommendationsJson)
        WITH (
            ClaimId BIGINT,
            CoverageTypeId SMALLINT,
            Payee VARCHAR(256),
            IndemnityPmtRequestAmnt MONEY,
            ExpensePaymentRequestAmnt MONEY,
            RequestDate DATETIME,
            Memo VARCHAR(MAX), -- 补全完整的数据类型,可根据实际表结构调整长度
            CheckNumber VARCHAR(50), -- 示例长度,按需修改
            IssueDate DATETIME,
            CreatedOn DATETIME,
            CreatedBy VARCHAR(128),
            ModifiedOn DATETIME,
            ModifiedBy VARCHAR(128)
        )
    ) AS Source
    -- 关键:定义匹配规则(这里假设ClaimId+CoverageTypeId是联合唯一键,需根据你的表主键调整)
    ON Target.ClaimId = Source.ClaimId 
    AND Target.CoverageTypeId = Source.CoverageTypeId

    -- 匹配到现有记录则执行更新
    WHEN MATCHED THEN
        UPDATE SET
            Target.Payee = Source.Payee,
            Target.IndemnityPmtRequestAmnt = Source.IndemnityPmtRequestAmnt,
            Target.ExpensePaymentRequestAmnt = Source.ExpensePaymentRequestAmnt,
            Target.RequestDate = Source.RequestDate,
            Target.Memo = Source.Memo,
            Target.CheckNumber = Source.CheckNumber,
            Target.IssueDate = Source.IssueDate,
            Target.ModifiedOn = Source.ModifiedOn,
            Target.ModifiedBy = Source.ModifiedBy

    -- 无匹配记录则插入新数据
    WHEN NOT MATCHED BY TARGET THEN
        INSERT (
            ClaimId, 
            CoverageTypeId, 
            Payee, 
            IndemnityPmtRequestAmnt, 
            ExpensePaymentRequestAmnt, 
            RequestDate, 
            Memo, 
            CheckNumber, 
            IssueDate, 
            CreatedOn, 
            CreatedBy, 
            ModifiedOn, 
            ModifiedBy
        )
        VALUES (
            Source.ClaimId, 
            Source.CoverageTypeId, 
            Source.Payee, 
            Source.IndemnityPmtRequestAmnt, 
            Source.ExpensePaymentRequestAmnt, 
            Source.RequestDate, 
            Source.Memo, 
            Source.CheckNumber, 
            Source.IssueDate, 
            Source.CreatedOn, 
            Source.CreatedBy, 
            Source.ModifiedOn, 
            Source.ModifiedBy
        )

    -- 目标表存在但JSON中没有的记录,执行删除
    WHEN NOT MATCHED BY SOURCE THEN
        DELETE;
END
GO

重要注意事项

  • 匹配条件要精准:确保ON子句使用的是表的主键或唯一约束,否则会出现重复更新/插入的逻辑错误。
  • 字段类型需一致:OPENJSON WITH中的数据类型必须和PaymentRecommendations表的字段类型完全匹配,避免隐式转换导致的异常。
  • 删除逻辑的风险:WHEN NOT MATCHED BY SOURCE THEN DELETE会删除所有不在JSON中的表记录,如果只需要删除特定范围的记录(比如某个Claim下的),需要在USING子查询中添加过滤条件,或者调整匹配规则。
  • 自增主键处理:如果你的表有自增ID字段,不要在INSERT列表中包含它,除非你显式执行SET IDENTITY_INSERT PaymentRecommendations ON。

内容的提问来源于stack exchange,提问作者Kaishu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:16:21