Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
199 views
in Technique[技术] by (71.8m points)

c# - SQL parametrized query for restoring backup file

I want to refactor the following sql query using parametrized query. Is it possible?

 string cmd= $@" IF EXISTS(select * from sys.databases where name='{ dbname}')
                                    ALTER DATABASE[{ dbname}] 
                                    SET OFFLINE WITH ROLLBACK IMMEDIATE;

                                    RESTORE DATABASE[{ dbname}]  
                                    FROM DISK = '{backupFile}'
                                    WITH REPLACE,
                                    MOVE '{mdfFileName}' TO '{sqlDataFolderPath}{dbname}.MDF',   
                                    MOVE '{logFileName}' TO '{sqlDataFolderPath}{dbname}.LDF';

                                    ALTER DATABASE[{ dbname}] 
                                    SET ONLINE ";

            SqlCommand cmd= con.CreateCommand();
            command.CommandText = sqlCommand;
            command.ExecuteNonQuery();

As a first step I used a parametrized query to retrive the information regarding mdf and ldf via RESTORE FILELISTONLY FROM DISK = @backupFilePath. And the next step should be the restore operation. Currently is working only with the above approach but I would like to refactor it in order to solve the security hotspot reported by sonar (sql injection) .

UPDATE:

I've tried to use the same approach as for BACKUP but without success, no error is thrown but the mdf, ldf files are not moved.

string sqlDynamicQuery = "DECLARE @sql nvarchar(max) = (" +
                                         "SELECT 'ALTER DATABASE ' + QUOTENAME(name) + " +
                                         "' SET OFFLINE WITH ROLLBACK IMMEDIATE;'" +
                                         "+ ' RESTORE DATABASE ' + QUOTENAME(name) + " +
                                         "' FROM DISK = @backupfilepath WITH REPLACE, " +
                                         "MOVE @mdfFileName TO @mdfFilePath, " +
                                         "MOVE @logFileName TO @ldfFilePath ' " +
                                         "+ ' ALTER DATABASE ' + QUOTENAME(name) +" +
                                         "'SET ONLINE ' from sys.databases where name= @database); "+
                                         "EXEC sp_executesql "+
                                         "@sql, " +
                                         "N'@backupfilepath nvarchar(128), @mdfFileName nvarchar(128),  @mdfFilePath  nvarchar(128), @logFileName nvarchar(128),  @ldfFilePath  nvarchar(128)', "+
                                         "@backupfilepath = @backupfilepath, "+
                                         "@mdfFileName = @mdfFileName, "+
                                         "@mdfFilePath = @mdfFilePath, "+
                                         "@logFileName = @logFileName, "+
                                         "@ldfFilePath = @ldfFilePath; ";

                using (SqlCommand sqlCmd = new SqlCommand(sqlDynamicQuery, _sqlConnection))
                {
                    sqlCmd.Parameters.Add("@database", SqlDbType.NVarChar, 128).Value = databaseName;
                    sqlCmd.Parameters.Add("@backupfilepath", SqlDbType.NVarChar, 128).Value = backupFile;
                    sqlCmd.Parameters.Add("@mdfFileName", SqlDbType.NVarChar, 128).Value = model.MdfFileName;
                    sqlCmd.Parameters.Add("@mdfFilePath", SqlDbType.NVarChar, 128).Value = Path.Combine(_sqlDataFolderPath, databaseName + ".MDF");
                    sqlCmd.Parameters.Add("@logFileName", SqlDbType.NVarChar, 128).Value = model.LogFileName;
                    sqlCmd.Parameters.Add("@ldfFilePath", SqlDbType.NVarChar, 128).Value = Path.Combine(_sqlDataFolderPath, databaseName + ".LDF");

                    sqlCmd.ExecuteNonQuery();
                }
   

I have also tried in ssms

DECLARE @database nvarchar(128)
DECLARE @backupfilepath nvarchar(128)
DECLARE @mdfFilePath nvarchar(128)
DECLARE @ldfFilePath nvarchar(128)
DECLARE @mdfFileName nvarchar(128)
DECLARE @logFileName nvarchar(128)

SET @database = 'v1'
set @backupfilepath = 'C:\Data\MyDocs\DatabaseBak\v1.bak'
SET @mdfFileName = 'p1'
SET @logFileName = 'p1_log'
SET @mdfFilePath = 'C:\Program Files\Microsoft SQL Server\MSSQL12.SQLEXPRESS\MSSQL\DATA\v1.MDF'
SET @ldfFilePath = 'C:\Program Files\Microsoft SQL Server\MSSQL12.SQLEXPRESS\MSSQL\DATA\v1.LDF'



DECLARE @sql nvarchar(max) = (SELECT 'ALTER DATABASE ' + QUOTENAME(name) + ' SET OFFLINE WITH ROLLBACK IMMEDIATE;' +  ' RESTORE DATABASE ' + QUOTENAME(name) + ' FROM DISK = @backupfilepath WITH REPLACE, MOVE @mdfFileName TO @mdfFilePath, MOVE @logFileName TO @ldfFilePath '+ ' ALTER DATABASE ' + QUOTENAME(name) + 'SET ONLINE  ' from sys.databases where name= @database);
print @sql
EXEC sp_executesql
    @sql,
    N'@backupfilepath nvarchar(128), @mdfFileName nvarchar(128),  @mdfFilePath  nvarchar(128), @logFileName nvarchar(128),  @ldfFilePath  nvarchar(128)',
    @backupfilepath = @backupfilepath,
    @mdfFileName = @mdfFileName,
    @mdfFilePath = @mdfFilePath,
    @logFileName = @logFileName,
    @ldfFilePath = @ldfFilePath;

UPDATE:

It works now on SSMS:

DECLARE @database nvarchar(128)
DECLARE @backupfilepath nvarchar(128)
DECLARE @mdfFilePath nvarchar(128)
DECLARE @ldfFilePath nvarchar(128)
DECLARE @mdfFileName nvarchar(128)
DECLARE @logFileName nvarchar(128)

SET @database = 'v1'
set @backupfilepath = 'C:\Data\MyDocs\DatabaseBak\v1.bak'
SET @mdfFileName = 'p1'
SET @logFileName = 'p1_log'
SET @mdfFilePath = 'C:\Program Files\Microsoft SQL Server\MSSQL12.SQLEXPRESS\MSSQL\DATA\v1.MDF'
SET @ldfFilePath = 'C:\Program Files\Microsoft SQL Server\MSSQL12.SQLEXPRESS\MSSQL\DATA\v1.LDF'


DECLARE @SQLString nvarchar(max) ='IF EXISTS(select * from sys.databases where name='+'''' + @database +''''+')'+
   'ALTER DATABASE [' + @database + '] ' +
   'SET OFFLINE WITH ROLLBACK IMMEDIATE ' +
   'RESTORE DATABASE ['+@database +
   '] FROM  DISK ='+ '''' + @backupfilepath +''''+
   ' WITH  REPLACE,  '+
   'MOVE '+''''+@mdfFileName+''''+ ' TO '+ '''' + @mdfFilePath +''''+',  '+
   'MOVE '+''''+@logFileName+''''+ ' TO '+ '''' + @ldfFilePath +''''+';  '+
   'ALTER DATABASE [' + @database + '] ' +
   'SET ONLINE '
print @SQLString


EXEC sp_executesql
    @SQLString,
    N'@database nvarchar(128), @backupfilepath nvarchar(128), @mdfFileName nvarchar(128),  @mdfFilePath  nvarchar(128), @logFileName nvarchar(128),  @ldfFilePath  nvarchar(128)',
    @database = @database,
    @backupfilepath = @backupfilepath,
    @mdfFileName = @mdfFileName,
    @mdfFilePath = @mdfFilePath,
    @logFileName = @logFileName,
    @ldfFilePath = @ldfFilePath;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...