【问题标题】: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。我已经仔细检查了要从中选择的表,并确保数据存在。

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

【问题讨论】:

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


    【解决方案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 个值)
      猜你喜欢
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 2020-08-17
      • 2012-01-18
      相关资源
      最近更新 更多