#c# #parsing #sql-server-ce #executenonquery
#c# #синтаксический анализ #sql-server-ce #executenonquery
Вопрос:
Я хочу запустить инструкцию sql, которую я сначала прочитал из .sql
файла.
Я получаю эту ошибку: {"There was an error parsing the query. [ Token line number = 13,Token line offset = 1,Token in error = ALTER ]"}
В .sql
файле есть моя инструкция sql:
CREATE TABLE [Test]
(
[Id] INT NOT NULL IDENTITY (1,1),
[DatabaseVersion] NVARCHAR(20) NOT NULL,
[Autorun] BIT,
[CurrentCulture] NVARCHAR(10),
[MailNotificationEnabled] BIT,
[RefreshInterval] INT,
[ModifiedDate] DATETIME NOT NULL,
[schemat] NVARCHAR(255)
)
ALTER TABLE [Test] ADD CONSTRAINT [PK_Test] PRIMARY KEY ([Id])
UPDATE [AppConfig]
SET [DatabaseVersion] = '0.12'
Чтение файла:
string oldVersion = GetOldDatabaseVersion();
string sqlScript = "";
sqlScript = GetScriptFromAssembly(oldVersion,
ConfigurationSettings.ValidDatabaseVersion);
ExecuteNonQuery(CommandType.Text, sqlScript);
ExecuteNonQuery
метод:
public int ExecuteNonQuery(CommandType type, string sql)
{
using (SqlCeConnection connection = CreateConnection())
{
return ExecuteNonQuery(connection, type, sql);
}
}
private int ExecuteNonQuery(SqlCeConnection connection, CommandType type, string sql)
{
using (SqlCeCommand command = new SqlCeCommand())
{
command.Connection = connection;
command.CommandType = type;
command.CommandText = sql;
return command.ExecuteNonQuery();
}
}
Я не знаю, как это решить. Когда я запускаю скрипт непосредственно в db, он работает.
Комментарии:
1. Я бы предположил, что SqlCommand нужно, чтобы команда была разделена на
;
? Это всего лишь предположение, потому что, похоже, оно не распознает, чтоALTER
запускает новый оператор.2. Я пробовал это ;/
3. Что я сейчас сделал — запускаю каждую инструкцию (create, alter и т.д.) Отдельно. Это работает. Но я не хочу создавать все инструкции в отдельных файлах ;/
Ответ №1:
Решена:
string sqlScript = GetScriptFromAssembly(GetOldDatabaseVersion(), ConfigurationSettings.ValidDatabaseVersion);
string[] scripts = sqlScript.Split(new string[] { @"/*$$*/" }, StringSplitOptions.None);
foreach(var script in scripts)
ExecuteNonQuery(CommandType.Text, script);
Добавлены разделители в sql:
CREATE TABLE [Test]
(
[Id] INT NOT NULL IDENTITY (1,1),
[DatabaseVersion] NVARCHAR(20) NOT NULL,
[Autorun] BIT,
[CurrentCulture] NVARCHAR(10),
[MailNotificationEnabled] BIT,
[RefreshInterval] INT,
[ModifiedDate] DATETIME NOT NULL,
[schemat] NVARCHAR(255)
)
/*$$*/
ALTER TABLE [Test] ADD CONSTRAINT [PK_Test] PRIMARY KEY ([Id])
/*$$*/
UPDATE [AppConfig]
SET [DatabaseVersion] = '0.12'
Ответ №2:
Вы должны запускать каждый оператор как отдельную команду, вы можете использовать код, подобный вспомогательной функции, для разделения на команды, если вы разделяете каждую команду с помощью GO:
https://github.com/ErikEJ/SqlCeToolbox/blob/master/src/API/Repositories/ServerDBRepository.cs#L639
Как вы можете видеть, для этого я использую SqlCommandReaderStreamed
из пакета DbUp
Ответ №3:
- Пожалуйста, используйте ключевое слово Go перед изменением таблицы
Комментарии:
1. afaik
GO
это не SQL и просто используется такими инструментами, как sql management studio, для разделения пакетов. Но она не передается на сервер, поэтому она не должна быть частью текста командыSqlCommand
.