Оператор динамического выбора, помещающий результат в переменную

#sql-server #tsql

#sql-сервер #tsql

Вопрос:

Я провел некоторый поиск, но ничего не дает того, что я ищу в точности. Я читал об EXEC (@variable), и это МОЖЕТ быть тем, что я хочу, но я не могу заставить это работать.

Идея в том, что есть несколько групп, которым я буду отправлять электронные письма в зависимости от места, в котором что-то произошло. Итак, мне нужно сохранить эту информацию в переменной, которую я затем могу передать @recipients в sp_send_dbmail.

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

Чтобы сделать это, я настроил другой регистр для объявления переменной на основе shift, удалил свой исходный регистр и создал таблицу конфигурации для shift a, b, c и т.д. Итак, что я хочу сделать, это

ВЫБЕРИТЕ @shift Из таблицы, В которой произошел этот дефект.

вот что я пытался сделать, но это не работает.

 SET @EmailRecipients = 'SELECT'    @EmailRecipientsCase   'FROM ScrapReasonProcessGroups WHERE ID = @ProcessCounter'
SET @EmailRecipients = EXEC(@EmailRecipients)
  

Ответ №1:

Использовать CASE без динамического SQL?

 SELECT @EmailRecipients = CASE @EmailRecipientsCase
                              WHEN 'shifta' THEN ShiftA
                              WHEN 'shiftb' THEN ShiftB
                              WHEN 'shiftc' THEN ShiftC
                          END
FROM ScrapReasonProcessGroups
WHERE ID = @ProcessCounter
  

Комментарии:

1. Похоже, что это сработает … но если это так просто, почему бы просто не удалить этот оператор CASE в запросе? Зачем делать это динамическим запросом?

2. @Philip Kelley: Мой ответ — не динамический SQL, а классический «назначить переменную в SELECT». В первой строке действительно сказано «Использовать РЕГИСТР без динамического SQL».

Ответ №2:

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

 CREATE TABLE #tmpEmail (
    EmailAddress varchar(200)
)

SET @EmailSQL = 'SELECT '    @EmailRecipientsCase   ' FROM ScrapReasonProcessGroups WHERE ID = '   @ProcessCounter

INSERT INTO #tmpEmail
    (EmailAddress)
    EXEC (@EmailSQL)
  

Комментарии:

1. Этот метод определенно имеет наибольший смысл и, похоже, он должен сработать. Единственная проблема в том, что по какой-то причине ему это не нравится: «Необходимо объявить скалярную переменную «@ProcessCounter». Эта переменная определенно уже объявлена и работала без каких-либо проблем, пока я не внес это изменение

2. @Tom: Это динамический SQL с конкатенацией строк. Что, если @EmailRecipientsCase — это 1; DELETE Users-- … классическая SQL-инъекция

3. Чтобы заставить ваш код работать, я пропустил приведение int. УСТАНОВИТЕ @EmailRecipients = ‘SELECT ‘ @EmailRecipientsCase ‘ ИЗ ScrapReasonProcessGroups, ГДЕ ID = ‘ приведите (@ProcessCounter как varchar) ВСТАВЬТЕ В @tmpEmail (адрес электронной почты) EXEC (@EmailRecipients) УСТАНОВИТЕ @EmailRecipients = (ВЫБЕРИТЕ * Из @tmpEmail) УДАЛИТЕ Из @tmpEmail