You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何创建可手动传入JSON文件路径的SQL Server存储过程?

嘿,我帮你瞅了下这个存储过程的问题,核心坑就在OPENROWSET的BULK参数不能直接用变量传——SQL Server这玩意儿不允许这么干,得用动态SQL绕一下才行。另外还有几个小细节可以优化,我给你改好了,咱们一步步说:

问题分析

  1. OPENROWSET(BULK)不支持直接传入变量作为路径参数,必须通过动态SQL拼接执行语句
  2. 原存储过程里的@json是输入参数,但后续被赋值覆盖,完全没必要留着当输入
  3. 插入表时没显式指定列名,万一表结构变了很容易出问题

修正后的存储过程代码

CREATE PROCEDURE main.mainRun 
    @path NVARCHAR(50)  -- 只保留路径参数,去掉多余的@json输入参数
AS 
BEGIN
    SET NOCOUNT ON; -- 避免返回额外的行数计数信息
    DECLARE @json NVARCHAR(MAX);
    DECLARE @dynamicSQL NVARCHAR(MAX);

    BEGIN TRY
        -- 用动态SQL拼接OPENROWSET语句,注意转义路径里的单引号防止注入
        SET @dynamicSQL = N'
            SELECT @json = BulkColumn 
            FROM OPENROWSET (BULK ''' + REPLACE(@path, '''', '''''') + ''', SINGLE_CLOB) as j;
        ';
        
        -- 执行动态SQL,把JSON内容赋值给@json变量
        EXEC sp_executesql @dynamicSQL, N'@json NVARCHAR(MAX) OUTPUT', @json = @json OUTPUT;

        IF(ISJSON(@json) = 1)
        BEGIN
            PRINT 'JSON File is valid';
            -- 显式指定目标列,避免表结构变化导致的错误
            INSERT INTO main.jsontable 
            (
                LoadDate, -- 假设你的表有这个存储加载时间的列
                name, 
                surname, 
                email, 
                age, 
                balance, 
                country, 
                registered
            )
            SELECT 
                GETDATE(),
                * 
            FROM OPENJSON(@json, '$.PersonDetails.Person') 
            WITH ( 
                name varchar(50) '$.first_name', 
                surname varchar(50) '$.last_name', 
                email varchar(50) '$.email', 
                age varchar(50) '$.age', 
                balance varchar(50) '$.balance', 
                country varchar(50) '$.country', 
                registered varchar(50) '$.registered' 
            );
        END
        ELSE
        BEGIN
            PRINT 'JSON File is invalid';
        END;
    END TRY
    BEGIN CATCH
        PRINT ERROR_MESSAGE();
    END CATCH
END;
GO

额外注意事项

  • 确保执行这个存储过程的账号有读取目标文件路径的权限,OPENROWSET需要文件系统的访问权限
  • 如果路径里有空格或特殊字符,不用担心,代码里的REPLACE(@path, '''', '''''')已经帮你转义了单引号,避免SQL注入和语法错误
  • 检查main.jsontable的列数据类型和顺序,要和SELECT语句的输出完全匹配,不然插入会失败

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

火山引擎 最新活动