Выберите скалярное значение из таблицы

Edit: Проблема, с которой я столкнулся, связана с смешиванием параметров в моем коде. Я искренне благодарю всех за помощь; мое понимание SQL улучшается при каждом посещении SO.

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

DECLARE @configVar int;
SET @configVar = (SELECT ExampleSetting FROM Settings WHERE SettingID = 1);
-- do something with @configVar to get the final result set

Очевидно, что (для людей с лучшим пониманием SQL) вышеуказанное неверно. Нет ошибки, кроме случаев, когда хранимая процедура выполняется, @configVar имеет значение NULL. Я дважды проверил таблицу, из которой я выбрал, и обеспечил, чтобы данные существовали.

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

Ответы

Ответ 1

TSQL позволяет устанавливать переменные в предложении SELECT, используя:

SELECT @configVar = s.examplesetting 
  FROM SETTINGS s
 WHERE s.settingid = 1

Это предполагает наличие только одной записи в таблице, где значение settingid равно 1.

Для получения дополнительной информации об использовании см. вопрос "TSQL - SET против SELECT при назначении переменных?".

Ответ 2

Очевидно (для людей с лучшим пониманием SQL), приведенное выше неверно.

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

SELECT @configVar = ExampleSetting FROM Settings WHERE SettingID = 1;

Фактически, это даст вам ошибку в первой форме, когда будет возвращено несколько строк (попробуйте следующий запрос), который позволяет вам знать, что что-то не так, как вы ожидаете, тогда как второй запрос выше бесшумно работает с помощью ExampleSetting значение из последней согласованной записи.

DECLARE @configVar int;
SET @configVar = (SELECT number FROM master..spt_values);
-- Msg 512, Level 16, State 1, Line 2
-- Subquery returned more than 1 value.

Запустите это самостоятельно, и вы увидите что-то, что вас удивляет.

SELECT ExampleSetting FROM Settings WHERE SettingID = 1

Если это не возвращает никаких записей, то почему SET @configVar остается NULL

FYI, это то, что я пробовал, и он работал как рекламируемый

DECLARE @configVar int;
SET @configVar = (SELECT top 1 number FROM master..spt_values);
select @configVar;
-- result: -32768

Единственное исключение из того, почему вы должны использовать форму SELECT @var вместо формы SET from subquery, состоит в том, что первая оставляет переменную в одиночку, когда запрос не находит соответствующих строк, второй явно устанавливает его в null.

DECLARE @configVar int;
SET @configVar = 123;
SET @configVar = (SELECT top 1 number FROM master..spt_values where 1=0);
select @configVar;  -- @configVar was set to NULL

SET @configVar = 123;
SELECT top 1 @configVar = number FROM master..spt_values where 1=0;
select @configVar;  -- @configVar is LEFT as 123

Ответ 3

DECLARE @configVar int;
SELECT @configVar  = ExampleSetting FROM Settings WHERE SettingID = 1

Ответ 4

Вместо этого вы должны сделать это:

SELECT @configVar = ExampleSetting FROM Settings WHERE SettingID = 1

Обратите внимание, что если ваш запрос возвращает более одной строки, ваша переменная будет равна последнему возвращенному значению в наборе.