C # и SQL Server: ExecuteNonQuery возвращает -1, когда UPDATE работает?

Приносим извинения, если об этом уже спрашивали. Я искал час и не нашел точной проблемы, с которой я столкнулся.

Я использую SMO для выполнения некоторых запросов к SQL Server, потому что я читал, что он может обрабатывать операторы GO, а не System.Data.SqlClient.

Я выполняю этот запрос:

SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS ON 
GO  

UPDATE Program
SET ENABLED = '1'
WHERE Program_ID = '64' AND Program_Name = 'DoesSomething' 

Я фиксирую "строки, затронутые":

int numberOfRows = db.ConnectionContext.ExecuteNonQuery(s.Query);

Проблема, с которой я столкнулся, заключается в том, что это каждый раз возвращает значение -1. Я проверяю базу данных за кулисами, и она ОБЯЗАТЕЛЬНО обновляет значение каждый раз, и когда я вручную запускаю запрос в SSMS, я получаю подтверждение (затронуто 1 строка).

После прочтения некоторых других сообщений я пришел к выводу, что проблема может заключаться в первых четырех строках этого запроса. Я удалил операторы GO, и запрос вернул значение 1 вместо -1.

Большинство запросов / сценариев, которые пишет моя группа, имеют GO, SET ANSI_NULLS ON и SET QUOTED_IDENTIFIER ON в значительной степени стандартные, поэтому они везде (еще одна проблема на другой день - я знаю, что в этом случае это чрезмерно / неактуально). Это как-то влияет на количество строк? Если да, то можете ли вы дать какое-то направление обходного пути или, возможно, другой способ получить этот результат?

И да ... Я знаю, что ExecuteNonQuery должен возвращать количество затронутых строк. Мне просто нужно знать, почему он не возвращает то, что я думаю (в данном случае 1).


person shindigwagon    schedule 05.04.2018    source источник
comment
Вы используете Entity Framework?   -  person Emdad    schedule 05.04.2018
comment
Is this affecting my row count somehow? Вы доказали, что это так, и у вас есть решение. Я не знаю, почему это имеет значение, но вы сказали, что дополнительные утверждения excessive/irrelevant in this case.   -  person Dan Wilson    schedule 05.04.2018
comment
GO не оператор (SQL) - это просто разделитель, используемый SQL Server Management Studio (и это причина, по которой использование обычного SQL не работает - поскольку GO на самом деле не является оператором SQL ....)   -  person marc_s    schedule 05.04.2018
comment
@marc_s, поэтому OP использует SMO, который может обрабатывать GO.   -  person Evk    schedule 05.04.2018
comment
@DanWilson Я настроил этот запрос как тест. Итак, в моем случае эти операторы бесполезны, но я пытаюсь создать небольшую программу, которая может их запускать, потому что я точно знаю, что эти операторы нужно будет использовать в более крупных запросах, которые создает моя команда, поэтому я пытаюсь чтобы запустить это, чтобы сгладить дела.   -  person shindigwagon    schedule 05.04.2018


Ответы (1)


GO - это пакетный сепаратор, используемый SQLCMD, OSQL и другими инструментами. Поскольку ServerConnection.ExecuteNonQuery SMO распознает команды SQLCMD, он обрабатывает пакет разделитель для вас и выполняет каждый пакет, который вы вводите в своем тексте. Значение «return» серии не является четкой командой, поскольку каждая партия может иметь свой собственный возврат (не говоря уже о том, что каждая партия может содержать несколько операторов). Так что я бы отнесся к этому «возвращаемому» значению с недоверием. Если вы хотите подтвердить количество обновленных строк, используйте предложение OUTPUT в UPDATE и получите набор результатов или назначьте @@ROWCOUNT выходной переменной.

person Remus Rusanu    schedule 05.04.2018
comment
Это кое-что проясняет. Спасибо за ясность. Позвольте мне задать этот вопрос. Предположим, что в качестве аргумента никто не добавляет предложение вывода в конец оператора обновления. Можно программно добавить в конец? Если да, возникнут ли с этим проблемы? Спрашивает, потому что в настоящее время никто не пишет запросы с предложениями вывода, и было бы трудно сделать это стандартом для всех наших команд. - person shindigwagon; 05.04.2018
comment
Нет, ты не можешь. Он должен быть встроен в оператор в нужном месте и изменяет семантику. Я бы предпочел сам разбить текст на пакеты (т.е. искать GOs) и убедиться, что вы выполняете только один пакет при каждом вызове. Затем вы можете решить, что означает «возврат» для каждого из них. - person Remus Rusanu; 05.04.2018
comment
Я не понимаю, почему ваша команда пишет запросы таким образом, а затем ожидает, что вы запускаете их с C #. Если они хотят запускать эти запросы из кода, им следует исправить способ написания запросов. - person Steve; 05.04.2018
comment
просто FYI, давно я написал библиотеку для обработки GO и других команд SQLCMD на "простом" C #, см. github.com/rusanu/com.rusanu.dbutil. - person Remus Rusanu; 05.04.2018
comment
@RemusRusanu круто. Я пойду в этом направлении. СПАСИБО! - person shindigwagon; 05.04.2018