Как хранимая процедура обрабатывается Sql Server и .Net

Я использую хранимую процедуру более 1,5 лет. Но я никогда не задумывался о том, как данные извлекаются из пользовательского интерфейса или внутри другой хранимой процедуры.

Когда я пишу простую хранимую процедуру. например.

CREATE PROCEDURE sp_test
AS
BEGIN
 SELECT * FROM tblTest --Considering table has 3 columns.
END

Как C# передает этот результат в DataTable.

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

CREATE PROCEDURE sp_testcall
AS
BEGIN
 @temp = exec sp_test -- I think this would be the way, never tried
END

Если приведенный выше пример кода верен, то в чем разница между использованием вышеуказанного метода и запросом на вставку записей во временную таблицу?

CREATE PROCEDURE sp_test
AS
BEGIN
 SELECT * INTO #tmp FROM tblTest --Considering table has 3 columns.
END

Казалось бы, копирование результата во временную таблицу требует дополнительных усилий со стороны sql-сервера. Но что будет происходить за кулисами? Будет ли он напрямую назначать ссылки на результат в параметр с табличным значением или он использует тот же процесс, что и временная таблица?

Мой вопрос может быть не ясен. Но я постараюсь улучшить.


person Shantanu Gupta    schedule 14.08.2010    source источник
comment
RE: Как C# передает этот результат в DataTable? Насколько я понимаю, результаты отправляются обратно в приложение C # с использованием протокола Tabular Datastream. Небольшое количество пояснений здесь stackoverflow.com/questions/322766/   -  person Martin Smith    schedule 14.08.2010
comment
@Martin: Хорошая ссылка, чтобы понять, как клиент-сервер взаимодействует в sql server-C#.   -  person Shantanu Gupta    schedule 14.08.2010


Ответы (2)


Для начального и среднего уровня вы всегда должны рассматривать таблицы #temp и переменные @table как две стороны одной медали. Хотя между ними есть некоторые различия, для всех практических целей они стоят одинаково и ведут себя почти одинаково. Единственное существенное отличие состоит в том, что переменные @table не подвергаются транзакциям и, следовательно, не затрагиваются откатами.

Если вы углубитесь в детали, таблицы #temp будут немного дороже в обработке (поскольку они являются транзакционными), но, с другой стороны, переменные @table имеют только время жизни области действия переменной.

Что касается других вопросов, поднятых вашим вопросом:

  • параметры табличных значений всегда доступны только для чтения и их нельзя изменить (вставить/обновить/удалить в них)
  • добавление набора результатов процедуры в таблицу (реальная таблица, таблица #temp или переменная @tabel не имеет значения) может быть выполнено только с помощью INSERT INTO <table> EXEC sp_test
  • как правило, процедура, которая дает результат, который необходим в другой процедуре, вероятно, лучше, чем функция, определяемая пользователем.

Эрланд Соммарског подробно проанализировал тему обмена данными между процедурами, см. Как обмениваться данными между хранимыми процедурами< /а>.

person Remus Rusanu    schedule 14.08.2010
comment
Очень хорошее объяснение. Я узнал что-то новое из вашего ответа. Иногда бывают ситуации, когда невозможно создать UDF из-за операций DML. В этих случаях нам нужно вызывать процедуры с помощью процедур. - person Shantanu Gupta; 14.08.2010
comment
Правда, не все возможное в СП возможно в УДФ - person Remus Rusanu; 14.08.2010

select означает "возврат данных клиенту". C# — это клиент, поэтому он получает данные.
Опять же, это делает не C#, а ADO.NET. Существует поставщик данных, который знает, как использовать сеть/память/какой-то другой протокол для связи с сервером SQL и чтения потоков данных, которые он генерирует. Этот конкретный клиент (ADO.NET) использует полученные данные для создания определенных классов, таких как DataTable, другие провайдеры могут делать что-то совершенно другое.
Все это не имеет значения на уровне SQL Server, потому что, что касается сервера, данные были отправлены по протоколу, с которым было установлено соединение, и все.

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

Опять же, мне не совсем понятно, о чем вы спрашивали.

person GSerg    schedule 14.08.2010
comment
Спасибо за ответ. Получил ответ на первую часть своего вопроса. Моя вторая часть вопроса - это то, что происходит, когда я пишу процедуру, которая используется C #, а также некоторые другие хранимые процедуры. Но этот SP возвращает некоторую таблицу, например, указанную выше, то есть 1-й sp. Когда я использую этот 1-й SP для вызова во 2-м SP, мне нужен его результат. Можно ли его получить в Табличном параметре и какие усилия для этого необходимы. Будут ли эти усилия одинаковыми для использования при копировании данных из временной таблицы или получении результата в табличный параметр. Усилие по копированию данных, сделанное сервером Sql - person Shantanu Gupta; 14.08.2010