Пустая таблица возвращается после незначительного изменения хранимой процедуры - PullRequest
0 голосов
/ 30 января 2020

ОБНОВЛЕНИЕ см. Конец OP

этот заставляет нас чесать голову.

Мы написали метод в VB. NET, который заполняет DataTable

Выполняется следующее (упрощенно - код для создания экземпляров или установки элементов, устранена обработка ошибок)

Dim procedureName As String
Dim mnCommandTimeOut As Integer
Dim parameters As System.Data.OleDb.OleDbParameter()
Dim oConnection As System.Data.OleDb.OleDbConnection

'... все вышеперечисленное будет установлено во промежуточном коде. Тогда

Dim dataTable As System.Data.DataTable = Nothing
Dim oCommand As System.Data.OleDb.OleDbCommand = Nothing
oCommand = New System.Data.OleDb.OleDbCommand(procedureName, oConnection)
oCommand.CommandType = CommandType.StoredProcedure
oCommand.CommandTimeout = mnCommandTimeout

If parameters IsNot Nothing Then
    oCommand.Parameters.AddRange(parameters)
End If

Dim oAdapter As System.Data.OleDb.OleDbDataAdapter = Nothing
oAdapter = New System.Data.OleDb.OleDbDataAdapter()
oAdapter.SelectCommand = oCommand    

oAdapter.SelectCommand.CommandTimeout = 120
oAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
oAdapter.MissingMappingAction = MissingMappingAction.Passthrough
dataTable = New System.Data.DataTable()

oAdapter.Fill(dataTable)

Обратите внимание, что я также оставил код для очистки после себя, избавляясь от того, что нам больше не нужно, и так далее. Наш реальный код чище, чем этот!

Вот проблема

У меня есть SP, который вызывается с использованием вышеуказанного метода. Опять же, я не собираюсь go усложнять, но код в SP в основном состоит из чего-то вроде

SELECT Column1,
       Column2
  FROM <somequery>

Теперь мне нужно было внести изменения в этот SP, и добавил немного сложности

DECLARE @Table TABLE
       (Column1 <some type here>  PRIMARY KEY NOT NULL,
        Column2 <some type here>              NOT NULL)

Типы столбцов соответствуют исходным типам

INSERT
  INTO @Table
      (Column1,
       Column2)
SELECT <modified query>

, затем

SELECT [TAB].[Column1],
       [TAB].[Column2]
  FROM @Table [TAB]

Подводя итог Я еще не сделал ни одного значительные изменения в SP, кроме использования табличной переменной. Я не делаю прямой SELECT , но вместо этого я INSERT INTO Переменная таблицы, а затем я SELECT из этого. Я еще не представил никакой дополнительной сложности, которая мне нужна; когда я запускаю старый SP и новый SP через SQL Server Management Studio, я все равно получаю идентичный вывод там

Но не через вышеуказанный код в VB. NET

Используя старый SP, я получаю System.Data.DataTable, содержащий все строки, возвращенные SP. Используя новый SP, я получаю System.Data.DataTable, содержащий 0 столбцов и 0 строк.

ошибок не возникает Код работает идеально счастливо. Он просто возвращает пустую таблицу.

Становится хуже. У нас есть другой метод, который заполняет DataSet. Единственная разница между ним и оригинальной процедурой состоит в том, что мы определяем

Dim dataSet As System.Data.DataSet = Nothing
dataSet = New System.Data.DataSet()

и

oAdapter.Fill(dataSet)

И вот этот безумный бит. Совершенно непонятный безумный бит.

Когда я запускаю свой модифицированный SP с помощью метода набор данных , он возвращает набор данных. Набор данных содержит один набор данных, и угадайте, что, этот набор данных содержит все данные, которые возвращает мой SP.

Я сбит с толку. Что происходит на земле ? У кого-нибудь есть подсказка? Я подозреваю, что это как-то связано со мной, используя переменную таблицы, но что, как?

Я знаю, что вы собираетесь сказать: почему бы нам просто не использовать метод DataSet? Конечно. Но у нас есть обязательства по обратной совместимости. Там могут быть старые версии кода, вызывающие мой SP, используя старый метод. Я разработал свой SP так, чтобы он по-прежнему возвращал все те же данные, которые ожидают старые версии кода. Но я не могу изменить старые версии кода. Они по-прежнему используют метод, который использует DataTable. Поэтому я не могу дать им SP, который не будет работать для них .

Конечно, есть другое решение. Оставьте старый SP без изменений. Напишите новую версию SP, originalnamev2 или что-то в этом роде, которая будет использоваться новым программным обеспечением. Но я бы предпочел этого избежать. Плюс, конечно, это дает мне мурашки по коже. Мне нужно понять, , что больше не работает, поэтому я могу оценить, есть ли что-то еще в нашей кодовой базе, на которое мне нужно обратить внимание.

ОБНОВЛЕНИЕ начало

Хорошо - вот что я пытался

  1. Использовать переменную таблицы @Table, вставить туда строки, ВЫБРАТЬ строки. Результат : пусто DataTable
  2. Использовать фиксированную таблицу [dbo]. [TestTable]. Очевидно, что это НЕ решение для производства, но я сейчас пробую. SP теперь выполняет DELETE [dbo]. [TestTable], INSERT INTO [dbo]. [TestTable] и, наконец, SELECT строки. Результат : пусто DataTable
  3. Наконец я удалил все вставки и удаления из SP, и только строки SELECT. Результат : DataTable содержит строки

Возможное заключение: Именно наличие операторов DELETE и / или INSERT вызывает такое поведение.

Теперь, что мне нужно сделать, чтобы это работало? Почему это не работает, когда я использую адаптер для заполнения DataTable, но это работает, если я использую тот же адаптер для заполнения DataSet?

1 Ответ

0 голосов
/ 03 февраля 2020

Такое поведение было вызвано тем, что у моего SP отсутствует инструкция SET NOCOUNT ON вверху. Как только я добавил это, оно снова заработало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...