2016-07-29 99 views
0

我正在开发一个程序来拉XML文件,WordPress使您可以下载(本质上是一个备份副本)。OPENROWSET:sp_executesql语句在@param失败

此时我正在自动化该过程,以允许在SQL Server上频繁备份我的数据,由于某种原因,我一直在开发查询以运行OPENROWSET,其中XML文件将位于此处。

DECLARE @SQL NVARCHAR(MAX) 
DECLARE @ParamDefinition NVARCHAR(500) = N'@fstring NVARCHAR(MAX)' 
DECLARE @string VARCHAR(MAX) = 
N'C:\[FilePath]\Reviews\thehesperian2016-07-29.xml' 

SET @SQL = 
N'INSERT INTO #Temp (Extract_Date, XMLDATA) 
SELECT GETDATE() 
    , A.* 
FROM OPENROWSET(BULK @fstring, SINGLE_BLOB, CODEPAGE = ' + '''RAW''' + ') AS A' 

EXEC sp_executesql @SQL 
       , @ParamDefinition 
       , @fstring = @string 

错误:

Msg 102, Level 15, State 1, Line 4 
Incorrect syntax near '@fstring'. 

我可以把它变成在谓语表一个简单的查询,所以我有理由怀疑它是filepath被读取的方式。 我花了几个小时来试图弄清楚为什么这是错的。虽然我可以在BULKINSERT在此example使用QUOTENAME的,我希望能嵌入所有的,在动态SQL(因此仍使用sp_executesql

什么,或者为什么我这样做不对?任何帮助将不胜感激。 - 问候,

ANSWER

OPENROWSET - MSDN宣布在自己的一段话:

OPENROWSET does not accept variables for its arguments.

QUOTENAME就足够了,虽然我没有反正跑几个小REPLACE功能。

+0

在您的动态SQL中,@fstring被视为文字而不是变量。 – scsimon

+0

@scsimon right,忘记提及我通过proc参数调用fstring,所以SQL Server不应该从我的理解中猜出来。 –

+0

对于动态SQL,您必须使用+'''@var'''+ Concat,但仍不确定它是否在OPENROWSET中。我不认为它会工作 – scsimon

回答

1

OPENROWSET函数的数据文件路径不允许参数。相反,用文字构建所需的字符串:

DECLARE @string varchar(MAX) = N'C:\[FilePath]\Reviews\thehesperian2016-07-29.xml'; 
DECLARE @SQL nvarchar(MAX); 
SET @SQL = 
N'INSERT INTO #Temp (Extract_Date, XMLDATA) 
SELECT GETDATE() 
    , A.* 
FROM OPENROWSET(BULK ' + QUOTENAME(@string, '''') + ', SINGLE_BLOB, CODEPAGE = ''RAW'') AS A'; 
EXEC sp_execute @SQL; 

--EXECUTE(@SQL); 

UPDATE:

新增QUOTENAME的情况下,所提供的文件路径是从不受信任的来源。另外请注意,OPENROWSET queries are not autoparameterized。在这里执行sp_executesqlEXECUTE的查询是没有区别的。

+0

这确实破坏了使用sp_executesql的要点。另外,我没有提及@fstring在proc中作为参数被调用...所以理论上,SQL服务器应该能够把它当作一个变量,对吧? –

+0

@clifton_h,如果这是您的偏好,您可以使用'sp_executesql @ SQL'而不是'EXEC(@SQL)',但如果没有参数,则不需要这样做。文件名参数只允许使用文字字符串。 OPENROWSET不允许参数AFAIK。 –

+0

我会接受你的答案,除非它需要通过'QUOTENAME(@string,NCHAR(39))'清理变量。避免恶意使用。 –