执行“sp_executesql @sqlcommand”语法错误

时间:2012-07-25 22:20:01

标签: sql syntax

我正在设置一个SQL脚本,该脚本从变量名创建数据库,然后获取新创建的数据库并从.bak文件恢复它。我在我设置的一个命令中遇到了一些语法问题,并且想问一下是否有人可以帮助我发现我的语法错误?我只会粘贴我烦恼的代码片段及其声明,如果我是正确的,问题在于我声明文件名路径的方式。我已经尝试设置变量的路径,但由于撇号放置,我仍然收到错误。感谢!!!

declare @DBname varchar(10), @sqlcommand Nvarchar(max)
set @DBname = 'testdb'

创建数据库的代码,并将新数据库设置为单用户模式

--restore database
set @sqlcommand = N'Restore DATAbase ' + @DBname + ' from disk = ''C:/loc_smartz_db0_template.bak'' with move ' 
+ @DBname + ' to ''C:/ProgramFiles/Microsoft SQL Server/MSSQL/Data/TestDatabase1.mdf'', move ' +     @DBname + ' to ''C:/ProgramFiles/Microsoft SQL Server/MSSQL/Data/TestDatabase1.ldf'', Replace'
EXECUTE sp_executesql @sqlcommand 

将数据库设置回多用户的代码,并打印数据库已成功创建

2 个答案:

答案 0 :(得分:2)

看起来之前的海报已经修复了你的问题,但如果你以“最佳实践”方式使用动态sql,这可能已经避免了。将字符串连接在一起作为变量和字符串文字的混合并不理想,因为它使得使用撇号变得困难(如此处所示)。

更好的方法是将您的sql编写为

declare @DBname nvarchar(255) = 'testdb'
        ,@BakName nvarchar(255) = 'C:\loc_smartz_db0_template.bak'
        ,@MovemdfName nvarchar(255) = 'C:\Program Files\Microsoft SQL Server\MSSQL\Data\TestDatabase1.mdf'
        ,@MoveldfName nvarchar(255) = 'C:\Program Files\Microsoft SQL Server\MSSQL\Data\TestDatabase1.ldf'
        ,@sqlcommand nvarchar(max)
        ,@paramList nvarchar(max)

set @paramList = '@DBname nvarchar(255), @BakName nvarchar(255), @MovemdfName nvarchar(255), @MoveldfName nvarchar(255)'
set @sqlcommand = N'Restore DATAbase @DBname from disk = @BakName with move @DBname to @MovemdfName, move @DBname to @MoveldfName, Replace'

exec sp_executesql @statement = @sqlcommand
                  ,@params = @paramList
                  ,@DBname = @DBname
                  ,@BakName = @BakName 
                  ,@MovemdfName  = @MovemdfName 
                  ,@MoveldfName = @MoveldfName 

这样,您的sql命令非常易于阅读和维护。请注意,如果路径名中包含空格,则无需在变量值中转义撇号。

它还有一个优点(如果你有存储过程中的代码)允许SQL Server重用执行计划,这将提高性能。

有关详细信息,请参阅here

答案 1 :(得分:1)

两件事。

首先,您必须在数据库文件逻辑名称周围放置单引号,例如

来自

...with move testdb to 'C:/ProgramFiles/Microsoft SQL Server/MSSQL/Data/TestDatabase1.mdf'

...with move 'testdb' to 'C:/ProgramFiles/Microsoft SQL Server/MSSQL/Data/TestDatabase1.mdf'

制作

set @sqlcommand = N'Restore DATAbase ' + @DBname + ' from disk = ''C:\loc_smartz_db0_template.bak'' with move ''' 
 + @DBname + ''' to ''C:\ProgramFiles\Microsoft SQL Server\MSSQL\Data\TestDatabase1.mdf'', move '''
 + @DBname + ''' to ''C:\ProgramFiles\Microsoft SQL Server\MSSQL\Data\TestDatabase1.ldf'', Replace'

其次,使用反斜杠\,而不是斜杠。 (也许这有效,但在我的快速测试中没有。)