是否可以使用参数化查询执行BACKUP语句?

时间:2016-12-29 11:26:22

标签: c# sql-server ado.net

我使用上面的sql命令。但参数没有添加。我有2个文本框来指定位置和名称。但它没有传递给查询。任何解决方案?

SqlConnection con = new SqlConnection(CS);
con.Open();
SqlCommand cmd= new SqlCommand("BACKUP DATABASE BillingSoftware TO DISK = '@Loc:\\@Name.BAK'",con);

cmd.Parameters.AddWithValue("@Loc", textBox_BackupDatabaseLocation.Text);
cmd.Parameters.AddWithValue("@Name", textBox_BackupDatabaseName.Text);
cmd.ExecuteNonQuery();

3 个答案:

答案 0 :(得分:0)

由于您需要单独连接disk location和数据库backup filename,因此应添加+以连接两者以获取bak文件的绝对路径。

尝试使用以下查询:

SqlCommand cmd= new SqlCommand("BACKUP DATABASE BillingSoftware TO DISK = @Loc + ':\\' + @Name + '.BAK'",con);

答案 1 :(得分:0)

由于在阅读完评论后,您需要单独传递这两个参数。您需要在每一行创建变量,然后用于连接,因为t-sql不允许直接连接变量。我找到了一个解决方法:

declare @drive varchar(max);declare @path varchar(max);declare @fullpath varchar(max);set @drive = @Loc + ':\\';set @path = @Name + '.bak' ;set @fullpath = @drive + @path;BACKUP DATABASE BillingSoftware TO DISK = @fullpath

它看起来有些额外,但会满足您的需求。谢谢我以后!

为了避免SQL注入,更好地在c#端连接文件名和路径:

string dbBackupName = "some name here.bak";
            SqlConnection con = new SqlConnection(CS);
            con.Open();
            SqlCommand cmd = new SqlCommand("BACKUP DATABASE BillingSoftware TO DISK = @dbFullName", con);

            cmd.Parameters.AddWithValue("@dbFullName", textBox_BackupDatabaseLocation.Text + "\\" + dbBackupName);
            cmd.ExecuteNonQuery();

答案 2 :(得分:0)

不要传递两个单独的参数并尝试在SQL脚本中连接它们,只需将完整路径作为单个参数传递。您可以使用System.IO.Path.Combine创建文件夹和文件名的有效路径:

var folder=textBox_BackupDatabaseLocation.Text;
var filename = textBox_BackupDatabaseName.Text;
var fullPath=Path.Combine(folder,filename);

//...
var cmd= new SqlCommand("BACKUP DATABASE BillingSoftware TO DISK = @fullPath",con);
cmd.Parameters.AddWithValue("@fullPath", fullPath);
cmd.ExecuteNonQuery();

Path.Combine生成正确的文件路径,即使文件夹名称中存在例如尾随或缺失的斜杠,这会使字符串连接中断。

另一种选择是避免 SQL语句并使用SQL Server Management Objects库。最后,SMO会生成SQL命令,但它会公开API中的所有功能,应该查找并指定其他选项非常容易。

我说应该因为文档不符合SQL Server标准。 class reference就在那里,但是示例......检查Backing Up and Restoring Databases and Transaction Logs。也许有一个更好的SO文档页面。

无论如何,示例代码可以被提炼为:

//Local server
var srv = new Server();  
var db = srv.Databases["AdventureWorks2012"];    
var bk = new Backup
         {
             Action = BackupActionType.Database,
             BackupSetDescription = "Full backup of Adventureworks2012",
             BackupSetName = "AdventureWorks2012 Backup",
             Database = "AdventureWorks2012",
             Checksum = true
         };

var bdi = new BackupDeviceItem(fullDestinationPath,DeviceType.File);  
bk.Devices.Add(bdi);  
bk.SqlBackup(srv);  

优点是您可以定位多个数据库,例如循环,获取进度通知等。

<强>更新

Path类包含可用于验证路径的方法,例如Path.IsPathRooted可用于检查路径是否为完整路径。其他System.IO类可用于验证,例如Directory.Exists检查文件夹是否存在。