修改: 我的问题源于我的代码中的参数顺序混合。我真诚地感谢大家的帮助;每次访问SO时,我的SQL理解都会变得更好。
我正在编写一个存储过程,需要从另一个表中选择一些信息才能完成它的工作。
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。我仔细检查了我正在选择的表,并确保数据存在。
有人可以告诉我我的误解在哪里,以及我该如何纠正它?看起来这可能是一个常见的习语;这通常是如何完成的?
答案 0 :(得分:34)
TSQL允许您使用以下命令在SELECT子句中设置变量:
SELECT @configVar = s.examplesetting
FROM SETTINGS s
WHERE s.settingid = 1
这假设表中只有一条记录值为1的记录。
有关使用情况的详情,请参阅问题“TSQL - SET vs. SELECT when assigning variables?”。
答案 1 :(得分:13)
显然(对于对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
留空的原因
仅供参考,这是我尝试过的,并且它像宣传的一样工作
DECLARE @configVar int;
SET @configVar = (SELECT top 1 number FROM master..spt_values);
select @configVar;
-- result: -32768
为什么要使用SELECT @var
形式而不是SET from subquery
形式的一个例外是,当查询找不到匹配的行时,第一个单独留下变量,第二个显式地将它设置为null。 / p>
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
答案 2 :(得分:5)
DECLARE @configVar int;
SELECT @configVar = ExampleSetting FROM Settings WHERE SettingID = 1
答案 3 :(得分:0)
你应该这样做:
SELECT @configVar = ExampleSetting FROM Settings WHERE SettingID = 1
请注意,如果您的查询返回多行,则您的变量将等于该集合中的最后一个返回值。