Выберите скалярное значение из таблицы
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
Обратите внимание, что если ваш запрос возвращает более одной строки, ваша переменная будет равна последнему возвращенному значению в наборе.