Как хранимая процедура обрабатывается Sql Server и .Net - PullRequest
2 голосов
/ 14 августа 2010

Я использую хранимую процедуру более 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.Но что будет происходить за кулисами?Будет ли он непосредственно присваивать ссылки на результат в табличный параметр или использует тот же процесс, что и временная таблица?

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

Ответы [ 2 ]

7 голосов
/ 14 августа 2010

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

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

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

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

Тема обмена данными между процедурами была подробно проанализирована Erland Sommarskog, см. Как обмениваться данными между хранимыми процедурами .

2 голосов
/ 14 августа 2010

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

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

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

...