从表中选择一个标量值

Posted

技术标签:

【中文标题】从表中选择一个标量值【英文标题】:Select a scalar value from a table 【发布时间】:2011-01-20 21:14:04 【问题描述】:

编辑: 我的问题源于代码中的参数顺序混淆。衷心感谢大家的帮助;每次访问 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。我已经仔细检查了要从中选择的表,并确保数据存在。

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

【问题讨论】:

【参考方案1】:

TSQL 允许您在 SELECT 子句中设置变量,使用:

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

这假设表中只有一条settingid值为1的记录。

有关使用的更多信息,请参阅问题“TSQL - SET vs. SELECT when assigning variables?”。

【讨论】:

@Conrad Frix:在我看到你的评论之前更正了。在我添加表别名时输入错误。 @OMG 小马。好吧,只是想知道这是不是我以前没见过的东西 @omg, @conrad - 虽然这显示了另一种编写方式,但它是否回答了问题? @cyberkiwi:我提供了一个正确语法的例子,并链接到一个比较使用两种有效语法的问题——“不回答问题”是怎么回事? 很抱歉根据我的愚蠢错误开始争论!即使我的错误是应该立即发现的,但我感谢您的所有回答帮助我更好地理解 SQL。【参考方案2】:

显然(对于对 SQL 有更好理解的人来说),以上是不正确的。

为什么要这么说?完全有效即使可以写成

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

事实上,当返回多行时(尝试下一个查询),它会在第一种形式中给您一个错误,这让您知道某些事情不是您所期望的,而上面的第二个查询静默 em> 使用最后匹配记录中的 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 的原因

仅供参考,这是我尝试过的,并且效果与宣传的一样

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

使用SELECT @var 表单而不是SET from subquery 表单的一个例外是,当查询找不到匹配的行时,第一个将变量单独保留,第二个将其显式设置为空。

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

【讨论】:

使用SET @configVar = (SELECT...); 格式,是否必须使用括号?我想知道这是否就是导致我出现语法错误的原因。 是的,你必须这样做。否则是语法错误。语法使代码能够准确地表达预期的内容。【参考方案3】:
DECLARE @configVar int;
SELECT @configVar  = ExampleSetting FROM Settings WHERE SettingID = 1

【讨论】:

【参考方案4】:

你应该这样做:

SELECT @configVar = ExampleSetting FROM Settings WHERE SettingID = 1

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

【讨论】:

说法不正确。它不会尝试将其设置为“一组”。它要么工作(null 或 value),要么会爆炸(子查询返回超过 1 个值)

以上是关于从表中选择一个标量值的主要内容,如果未能解决你的问题,请参考以下文章

设置影响嵌入式标量函数的行数

从表中选择多个列,但按一个分组

如果存在则从表中选择,否则从oracle中的另一个表中选择

从表中选择数据并从另一个表中填充特定值

从表中选择数组并加入另一个表中的 jsonb 对象

如何从表中选择记录并插入另一个表?