2016-12-29 4 views
1

Iam, используя команду sql. Но параметры не добавляются. У меня есть 2 текстовых поля для указания местоположения и имени. но не передавая запрос. Любое решение?Возможно ли выполнить оператор BACKUP с помощью параметризованного запроса?

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(); 
+0

Вы пытаетесь использовать параметры, как если бы они были переменными подстановки строки. Это не так.* Предполагая, что 'BACKUP DATABASE' принимает параметры, просто передайте полный путь как один параметр, то есть' TO DISK = @ fullPath' –

+0

Почему вы не просто передаете полный путь как единственный параметр? Вы можете построить правильное значение с помощью 'Path.Combine()' –

ответ

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

Во всяком случае, пример кода можно обобщить следующим образом:

//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); 

Преимущество заключается в том, что вы можете настроить таргетинг на несколько баз данных, например, в цикле, получать уведомления и т.д.

UPDATE

прогресс

Класс Path содержит методы, которые могут использоваться для проверки путей, например, Path.IsPathRooted может использоваться для проверки того, является ли путь полным путем. Другие классы System.IO могут использоваться для проверки, например Directory.Exists проверьте, существует ли папка.

+0

Хороший ответ .. Спасибо. – Abhijith

+0

Я должен ввести местоположение, подобное D: \ .. Я не хочу, чтобы пользователь вводил «: \». Как это сделать. – Abhijith

+0

@Abhijith вы имеете в виду, как проверить пути? Я добавил обновление. Вы можете использовать 'Path.IsPathRooted', чтобы проверить, является ли путь абсолютным, и/или' Directory.Exists', чтобы проверить, действительно ли папка существует. –

0

Поскольку вам нужно сцепить disk location и базу данных backup filename отдельно, вы должны добавить + для конкатенации как получить абсолютный путь к файлу Бака.

Попробуйте использовать следующий запрос:

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

. Хорошие ответы содержат некоторое объяснение не только кода – GuidoG

+0

Неправильный синтаксис рядом с '+'. – Abhijith

+0

Я сомневаюсь, что это сработает. Параметры могут быть заполнены, но + не будет приниматься сервером sql – GuidoG

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(); 
+0

Конкатенация строк - это * проблема *, а не решение. Параметрированные запросы используются для * избежания * конкатенации и SQL-инъекции –

+0

, в этом случае SQL-инъекция не будет, поскольку мы даем параметры. – Umar

+0

Нет, нет. Вы * конкатенируете строки * в самом скрипте. Если вы могли бы написать 'TO DISK = @ somepath', почему бы не передать полный путь в качестве параметра? –

Смежные вопросы