是否可以使用参数化查询执行 BACKUP 语句?
Is it possible to execute a BACKUP statement using a parameterised query?
我正在使用上面的 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();
因为你需要分别连接disk location
和数据库backup filename
,你应该添加+
来连接两者以获得bak文件的绝对路径。
尝试使用以下查询:
SqlCommand cmd= new SqlCommand("BACKUP DATABASE BillingSoftware TO DISK = @Loc + ':\' + @Name + '.BAK'",con);
看了大家的评论,需要分别传这两个参数。您需要在每一行创建变量,然后用于连接,因为 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();
与其传递两个单独的参数并尝试在 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 服务器标准。 class reference is there but the examples ... Check 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 class contains methods that can be used to validate paths, eg Path.IsPathRooted can be used to check whether the path is a full path. Other System.IO
classes can be used for validation, eg Directory.Exists 检查文件夹是否存在。
我正在使用上面的 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();
因为你需要分别连接disk location
和数据库backup filename
,你应该添加+
来连接两者以获得bak文件的绝对路径。
尝试使用以下查询:
SqlCommand cmd= new SqlCommand("BACKUP DATABASE BillingSoftware TO DISK = @Loc + ':\' + @Name + '.BAK'",con);
看了大家的评论,需要分别传这两个参数。您需要在每一行创建变量,然后用于连接,因为 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();
与其传递两个单独的参数并尝试在 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 服务器标准。 class reference is there but the examples ... Check 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 class contains methods that can be used to validate paths, eg Path.IsPathRooted can be used to check whether the path is a full path. Other System.IO
classes can be used for validation, eg Directory.Exists 检查文件夹是否存在。