简体   繁体   中英

Executing a “sp_executesql @sqlcommand” Syntax Error

I am setting up a SQL script that creates a database from a variable name, and then takes that newly created database and restores it from a .bak file. I am having issues with some syntax in one of my commands that I am setting up, and wanted to ask if anybody could help me spot my syntax error? I am only going to paste my troubled snippet of code and its declarations, and if I am correct the issue lies in the way that I am declaring the file name paths. I have tried setting the paths to variables, but I still received errors due to the apostrophe placement. Thanks!!!

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

Code to create database, and set new database to single user mode

--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 

Code that sets database back to multiuser, and prints that the database was successfully created

It looks like the previous posters have fixed your problem, but this may have been avoided if you had used dynamic sql in the 'best practice' manner. Concatenating the string together as a mixture of variables and string literals is not ideal as it makes working with apostrophes difficult (as shown here).

A better way is to write your sql as

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 

This way, your sql command is very easy to read and maintain. Note that you don't have to mess around with escaping the apostrophes in the variable values either if you have spaces in your pathnames.

It also has the advantage (if you have the code in a stored proc) of allowing SQL Server to reuse execution plans which will improve performance.

See here for more information.

Two things.

First, you have to put single quotes around the database file logical name, eg

from

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

to

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

making it

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'

Second, use backslashes \\ , not slashes. (Maybe this works, but it didn't in my quick tests.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM