从表中选择标量值

时间:2011-01-20 21:14:04

标签: sql sql-server sql-server-2005 tsql

修改: 我的问题源于我的代码中的参数顺序混合。我真诚地感谢大家的帮助;每次访问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。我仔细检查了我正在选择的表,并确保数据存在。

有人可以告诉我我的误解在哪里,以及我该如何纠正它?看起来这可能是一个常见的习语;这通常是如何完成的?

4 个答案:

答案 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

请注意,如果您的查询返回多行,则您的变量将等于该集合中的最后一个返回值。