数据类型varchar和varbinary(max)在add运算符中不兼容

时间:2016-11-23 18:41:11

标签: sql .net sql-server stored-procedures parameters

我正在尝试使用存储过程插入到FileTable中,其中FileStream,FileName,FilePath将被参数化。我试过这个,但它引发了一个错误

  

数据类型varchar和varbinary(max)在add运算符

中不兼容

我的存储过程:

    @filePath VARCHAR(100),
    @fileName VARCHAR(100)
AS
BEGIN
    DECLARE @file VARBINARY(MAX)
    DECLARE @sql NVARCHAR(max)

    SET @sql = 'SELECT'+ @file +' = CAST(bulkcolumn AS VARBINARY(MAX)) FROM OPENROWSET(BULK '+ @filePath +', SINGLE_BLOB) AS x'

    EXEC(@Sql);

    INSERT INTO dbo.FileStore(name, file_stream)
        SELECT @fileName, @file
END

1 个答案:

答案 0 :(得分:1)

主要问题是动态SQL中的@file变量。

SET @sql = 'SELECT'+ @file +' = CAST(bulkcolumn AS VARBINARY(MAX)) FROM OPENROWSET(BULK '+ @filePath +', SINGLE_BLOB) AS x'

执行此操作时,@ file变量将替换为变量的内容。因此,如果@file包含空字符串(''),则将解析为:

SELECT  = CAST(bulkcolumn....

如果@file为NULL,整个字符串将为NULL ..

如果需要在动态SQL中使用变量,即将值传递给动态SQL中的语句或从中检索值,则需要使用sp_executeSQL和@params。下面是完整的测试和测试示例。动态SQL语句中的@file变量“映射”到存储过程中的@file变量。 sp_executeSQL知道用动态SQL中@file变量中的任何内容填充@file变量。请注意,即使它们的名称相同,它们也是不同的变量。如果你来自.Net,动态SQL就像.net中的一个方法,它有自己的变量范围。如果它能让事情更清楚,你可以在动态SQL中为@file变量使用不同的名称。

declare @filePath VARCHAR(100) = 'insert full path'
     , @fileName VARCHAR(100) = 'insert file name';
DECLARE @file VARBINARY(MAX);
DECLARE @sql NVARCHAR(max);
declare @params nvarchar(max);


set @sql = N'SET @file = (SELECT BulkColumn FROM OPENROWSET(BULK N''' + @filePath + ''', SINGLE_BLOB) AS x)';
set @params = N'@file varbinary(max) OUTPUT';

print @sql;

EXEC sp_executesql @sql, @params, @file = @file OUTPUT;
select @file;