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

存储过程中用参数替代OPENROWSET字符串路径报错问题

解决OPENROWSET(BULK)无法使用变量作为文件路径的问题

这个问题很常见——SQL Server的OPENROWSET(BULK)语法不支持直接使用变量作为文件路径,它要求路径必须是字符串字面量,这就是你遇到两种错误的核心原因:

  • 加引号时,SQL把@JSONFileLocation当成了文件名本身,自然找不到对应文件;
  • 不加引号时,语法解析器找不到合法的字符串字面量,所以抛出Expecting STRING or TEXT_LEX的错误。

解决办法是用动态SQL来拼接包含文件路径的语句,通过sp_executesql执行并返回读取到的JSON内容。下面是修改后的完整存储过程:

ALTER PROCEDURE main.mainRun 
    @JSONFileLocation NVARCHAR(MAX) 
AS
BEGIN TRY
    DECLARE @Details NVARCHAR(MAX)
    DECLARE @SQL NVARCHAR(MAX)

    -- 拼接动态SQL,转义路径中的单引号避免语法错误
    SET @SQL = N'
        SELECT @DetailsOutput = BulkColumn 
        FROM OPENROWSET(BULK ''' + REPLACE(@JSONFileLocation, '''', '''''') + ''', SINGLE_CLOB) JSON'

    -- 执行动态SQL并将读取到的JSON内容输出到@Details变量
    EXEC sp_executesql 
        @SQL,
        N'@DetailsOutput NVARCHAR(MAX) OUTPUT',
        @DetailsOutput = @Details OUTPUT

    -- 后续的JSON解析与插入逻辑保持不变
    INSERT INTO main.jsontable (dateloaded,name,surname,email,age,balance,country,registered)
    (
        SELECT GETDATE(), 
               [Name],[Surname],[Email],[Age],[Balance],[Country],[Registered]
        FROM OPENJSON(@Details,'$.PersonDetails.Person')
        WITH(
            [Name] NVARCHAR(50) '$.first_name',
            [Surname] NVARCHAR(50) '$.last_name',
            [Email] NVARCHAR(50) '$.email',
            [Age] NVARCHAR(50) '$.age',
            [Balance] NVARCHAR(50) '$.balance',
            [Country] NVARCHAR(50) '$.country',
            [Registered] NVARCHAR(50) '$.registered'
        )
    )

    EXEC main.generateStatistics
END TRY
BEGIN CATCH
    SELECT CONCAT('Error Number:',ERROR_NUMBER(),'|Error Message:',ERROR_MESSAGE(),'|Error Procedure:',ERROR_PROCEDURE()) AS 'Error'
END CATCH;

关键修改说明:

  • REPLACE(@JSONFileLocation, '''', '''''')转义路径中的单引号,既避免了SQL拼接时的语法错误,也能防范简单的SQL注入风险;
  • 通过sp_executesql的输出参数@DetailsOutput,将动态SQL中读取到的JSON内容传递回主流程的@Details变量,保证后续逻辑能正常使用;
  • 动态SQL拼接完成后,SQL Server会将@JSONFileLocation的实际值作为文件路径解析,而不是把变量名当成文件名。

另外要注意:执行这个存储过程的数据库账号,需要拥有目标JSON文件所在路径的读取权限,否则还是会出现文件找不到的错误哦。

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

火山引擎 最新活动