Зачем нам нужен параметр табличного значения - PullRequest
0 голосов
/ 05 мая 2018

У нас есть доступ к фактической таблице внутри хранимых процедур. Тогда зачем передавать таблицу через параметр? Есть ли какое-то особое преимущество?

1 Ответ

0 голосов
/ 05 мая 2018

Табличные параметры необходимы для передачи табличных данных в хранимую процедуру или функцию способом, который является «безопасным», особенно из клиентского кода (например, SqlCommand и SqlParameter).

Основной альтернативный метод заключается в создании и INSERT в #temporaryTable перед вызовом sproc, но временные таблицы не являются точно временными и существуют в tempdb, что создает проблемы с пространством имен и параллелизмом. Вам также придется использовать динамический SQL, потому что вы не можете параметризировать имена таблиц. С невременными таблицами действуют те же проблемы.

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

Также абсолютно необходимо, если один FUNCTION хочет передать табличные данные в другую функцию по той же причине, что и для чтения: функция не может создать #temporarytable, но она может создавать и заполнять табличные значения параметр.

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

Пример

Предположим, что код вашего приложения должен передать список кортежей (или список первичных ключей) хранимой процедуре или FUNCTION - или если существующий спрок или функция должны передать данные другой функции.

Используя временные таблицы, ваш код должен сделать это:

  1. Создать и открыть SqlConnection.
  2. Создайте и начните TRANSACTION.
  3. Создать новый #temporarytable
    • Временные таблицы относятся к текущему сеансу базы данных. Это нормально для большинства целей, но это означает, что вы не можете выполнять несколько одновременных операций с базой данных для этой временной таблицы в одном сеансе.
  4. LOCK любые обычные таблицы, которые вы будете использовать при необходимости, потому что ваша операция будет охватывать несколько SqlCommand выполнений.
  5. В клиентской или исходной хранимой процедуре выполните оператор INSERT, чтобы заполнить временную таблицу. Если вы вставляете данные из клиентского приложения, вам может понадобиться выполнить однорядную операцию INSERT также много раз - это очень неэффективно, особенно в средах с высокой задержкой, поскольку протокол TDS, используемый SQL Server, очень болтлив (как ни странно, вы можете выполнить одну многорядную операцию INSERT, используя SqlCommand, но вы должны использовать параметр с табличными значениями для хранения нескольких строк данных).
  6. Вызовите sproc или FUNCTION, который будет использовать временную таблицу.
  7. Снесите #temporaryTable, если вы будете поддерживать сеанс в живых, или немедленно завершите сеанс, чтобы не допустить потери памяти.

Но если вы используете параметр Table-Valued, это намного проще:

  1. Создать и открыть SqlConnection.
  2. Создайте и начните TRANSACTION.
  3. Создайте свой SqlCommand объект, который будет вызывать ваш sproc или FUNCTION, но вы можете напрямую использовать параметр с табличным значением и заполнить его все от клиента за один проход. Затем клиентское программное обеспечение отправляет поток данных таблицы на сервер за одну операцию, которая намного эффективнее.
  4. Затем спрок начинает бежать. Нет необходимости в завершении или завершении сеанса.
...