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

如何在SQL存储过程的JSON路径中传入@TargetIndex参数

解决SQL存储过程中JSON数组索引参数传入问题

你的问题核心是SQL Server的OPENJSON WITH子句不支持直接在JSON路径中引用变量,所以@TargetIndex无法直接嵌入到N'$.TargetField[@TargetIndex].field'这类路径里。以下是两种可行的解决方案:


方案一:使用动态SQL拼接完整查询语句

通过拼接字符串生成包含索引参数的JSON路径,再执行动态SQL:

CREATE PROCEDURE YourProcedureName
    @ReferenceID int,
    @BureausID int,
    @EmployersID int, 
    @FileType varchar(12),
    @TargetIndex int
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @SQL nvarchar(max);
    -- 拼接动态SQL,将@TargetIndex代入JSON路径
    SET @SQL = N'
        SELECT 
            SalesOrderJsonData.* 
        FROM 
            MapHistories AS Tab
        CROSS APPLY 
            OPENJSON(Tab.MapJSON, N''$.Mapping'') 
                WITH 
                (
                    ReferenceNumber int N''$.ReferenceNumber'',
                    target_field nvarchar(max) N''$.TargetField[' + CAST(@TargetIndex AS nvarchar) + '].field'', 
                    output_field_description nvarchar(max) N''$.TargetField[' + CAST(@TargetIndex AS nvarchar) + '].output_field_description''
                ) AS SalesOrderJsonData
        WHERE Tab.ReferenceID = @ReferenceID AND Tab.BureausID = @BureausID AND Tab.EmployersID = @EmployersID AND Tab.FileType = @FileType
    ';
    -- 执行动态SQL,传入其他参数
    EXEC sp_executesql @SQL, 
        N'@ReferenceID int, @BureausID int, @EmployersID int, @FileType varchar(12)',
        @ReferenceID = @ReferenceID,
        @BureausID = @BureausID,
        @EmployersID = @EmployersID,
        @FileType = @FileType;
END

注意:动态SQL要注意SQL注入风险,这里@TargetIndex是int类型,转换为字符串后不会有注入问题;如果是字符串参数需要用参数化传递。


方案二:先解析TargetField数组,再按索引筛选

先把TargetField数组单独解析出来,筛选出指定索引的元素,再和主Mapping数据关联:

CREATE PROCEDURE YourProcedureName
    @ReferenceID int,
    @BureausID int,
    @EmployersID int, 
    @FileType varchar(12),
    @TargetIndex int
AS
BEGIN
    SET NOCOUNT ON;
    SELECT 
        MappingData.ReferenceNumber,
        TargetFieldData.field AS target_field,
        TargetFieldData.output_field_description
    FROM 
        MapHistories AS Tab
    CROSS APPLY 
        OPENJSON(Tab.MapJSON, N'$.Mapping') 
            WITH 
            (
                ReferenceNumber int N'$.ReferenceNumber',
                TargetField nvarchar(max) N'$.TargetField' AS JSON -- 将TargetField作为JSON数组保留
            ) AS MappingData
    CROSS APPLY 
        OPENJSON(MappingData.TargetField)
            WITH 
            (
                field nvarchar(max) N'$.field',
                output_field_description nvarchar(max) N'$.output_field_description'
            ) AS TargetFieldData
    -- 筛选指定索引的元素(OPENJSON的默认索引从0开始)
    WHERE TargetFieldData.[key] = CAST(@TargetIndex AS nvarchar)
      AND Tab.ReferenceID = @ReferenceID 
      AND Tab.BureausID = @BureausID 
      AND Tab.EmployersID = @EmployersID 
      AND Tab.FileType = @FileType;
END

这个方案不需要动态SQL,更安全,适合需要避免动态SQL的场景。注意[key]是OPENJSON解析数组时返回的默认索引列,类型为nvarchar,所以需要和@TargetIndex的字符串形式匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:50:11