Выполнение пакетных сценариев T-SQL, содержащих инструкции GO, вызывает исключение

#c# #.net #sql-server

#c# #.net #sql-сервер

Вопрос:

Я пытаюсь выполнить SQL-скрипты, содержащие инструкции GO, со следующим кодом

 SqlConnection sqlConnection = new SqlConnection(RConnString);
ServerConnection svrConnection = new ServerConnection(sqlConnection);
Server server = new Server(svrConnection);
returnvalue = server.ConnectionContext.ExecuteNonQuery(strSpScript);
return Convert.ToString(returnvalue);
 

Но он выдает следующий excetpion в режиме реального времени. этот код отлично работает на моем локальном компьютере

Исключение было вызвано целью вызова. в System.RuntimeMethodHandle.invokeMethod(цель объекта, аргументы объекта [], сигнатура sig, логический конструктор) в системе.Размышления.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] параметры, Object[] аргументы) в системе.Отражение.RuntimeMethodInfo.Вызвать(Object obj, BindingFlags invokeAttr, Binder binder, параметры объекта[], CultureInfo culture) в System.RuntimeType.InvokeMember(строковое имя, BindingFlags BindingFlags, Binder binder, Object target, Object[] providedArgs, модификаторы ParameterModifier[], CultureInfo culture, String[] namedParams) в Microsoft.SQLServer.Management.Обычный.Подключение к серверу.GetStatements(строковый запрос, ExecutionTypes executionType, Int32и statementsToReverse) в Microsoft.SQLServer.Management.Обычный.Подключение к серверу.ExecuteNonQuery(строка SqlCommand, ExecutionTypes executionType) в Microsoft.SQLServer.Management.Обычный.Подключение к серверу.ExecuteNonQuery(строка SqlCommand)

Комментарии:

1. каков ваш sql-код?

2. в коде sql есть sql-скрипт sp с операторами go

3. GO это команда, которую клиентские инструменты должны использовать, чтобы знать, как разделить скрипт на отдельные пакеты и отправлять пакеты на SQL Server по отдельности. Теперь вы выступаете в роли клиентского инструмента, поэтому ваш код должен выполнить ту же задачу — найти GO буквы s (соблюдая осторожность с текстом в кавычках и комментариях) — и выполнить каждый пакет отдельно.

Ответ №1:

GO не существует в T-SQL. Это особенность таких инструментов, как SQL Server Management Studio, а не самого языка. Вместо этого вы должны найти любой GO из них и разделить команду там, выполнив их отдельно. В качестве альтернативы, реорганизуйте свой T-SQL для работы без GO него — во многих случаях EXEC это может помочь здесь.

Ответ №2:

Используйте код, подобный следующему:

 using (var connection = new SqlConnection(RConnString)) 
{
    connection.Open();
    foreach (var batch in strSpScript.Split(new string[] {"nGO", "ngo"}, StringSplitOptions.RemoveEmptyEntries))
    {
         try
         {
             new SqlCommand(batch, connection).ExecuteNonQuery();
         }
         catch (Exception ex)
         {
             Console.WriteLine(ex.Message);
             throw;
         }
    }
}
 

Это будет работать только в том случае, если у вас есть ‘GO’ в новой строке (и в согласованном случае) — измените по мере необходимости.

Комментарии:

1. Чтобы быть совместимым с другими клиентскими инструментами, вам также необходимо избегать разделения кода, когда GO он существует в многострочном комментарии или многострочном строковом литерале

2. поскольку мне приходится разделять Sps и выполнять в цикле, для большей безопасности я могу использовать некоторый уникальный код в новой строке, например ‘GO ##’, и разделить его

3. @Damien_The_Unbeliever — да, это не очень хороший код общего назначения, но если вы хотите что-то быстрое и грязное, не требующее написания синтаксического анализатора, и вы управляете вводом, это сделает свою работу.

4. @Sagar да, это будет работать, но преимущество использования GO заключается в том, что ваши скрипты затем переносятся на разные клиенты, так что, например, вы можете открыть свой скрипт в Management Studio для отладки.