Sql server 如何克服子查询的“iif”限制?

Sql server 如何克服子查询的“iif”限制?,sql-server,tsql,Sql Server,Tsql,我有两个表A和表B。我想对表B实现这样的逻辑: 我得到一个错误:在此上下文中不允许子查询。只允许使用标量表达式 有没有一种方法可以在创建表时实现这种逻辑?这看起来并不难。在阅读了评论中的讨论后,我感觉这是朝着错误的方向发展。可能是因为你对IIF的直接提问 如果我没有弄错,您可以尝试向表中添加一个计算列。沿着这一点: DECLARE @tblTest TABLE (ID INT IDENTITY ,SomeValue VARCHAR(100)

我有两个表A和表B。我想对表B实现这样的逻辑:

我得到一个错误:在此上下文中不允许子查询。只允许使用标量表达式


有没有一种方法可以在创建表时实现这种逻辑?这看起来并不难。

在阅读了评论中的讨论后,我感觉这是朝着错误的方向发展。可能是因为你对IIF的直接提问

如果我没有弄错,您可以尝试向表中添加一个计算列。沿着这一点:

DECLARE @tblTest TABLE (ID INT IDENTITY
                       ,SomeValue VARCHAR(100)
                       ,[Test] AS IIF(SomeValue IS NOT NULL, CONCAT(SomeValue,'Blah'), 'Default if null'));

INSERT INTO @tblTest(SomeValue) VALUES('Test');
INSERT INTO @tblTest(SomeValue) VALUES(NULL);

SELECT * FROM @tblTest;
结果

ID  SomeValue   Test
1   Test        TestBlah
2   NULL        Default if null
ID  SomeValue   Test
1   Test        wanted
2   NULL        Default if null
现在,您不仅希望从一些简单的标量计算中获取计算列的值,还希望从表中选取它

在这里,我将尝试模拟您的问题。下次由你自己来做。提供DDL、样本数据和预期输出以及您自己的尝试是获得您正在等待的答案的最佳机会

这是要从中获取值的表B。 稍后,我们将要求“测试”,而不是“xyz”

-这就是你正在尝试做的,但是由于你的错误,我把它注释掉了。 -计算列不允许选择。这不受IIF的约束

-但我们可以做的是——错误消息告诉我们——提供一个标量表达式: -标量函数正是这样的:

CREATE FUNCTION dbo.GetMyComputedColumn(@Condition VARCHAR(100)) 
RETURNS VARCHAR(100) AS 
BEGIN 
    RETURN (SELECT b.SomeResultColumn --You might use `TOP 1` to ensure a scalar result
            FROM tblB b 
            WHERE b.SomeConditionColumn=@Condition); 
END
GO
-我们可以在IIF中使用此函数:

结果

ID  SomeValue   Test
1   Test        TestBlah
2   NULL        Default if null
ID  SomeValue   Test
1   Test        wanted
2   NULL        Default if null
你应该这样做吗? 如果这是个好主意,那么问题就完全不同了

除了标量函数被称为性能不佳的事实之外,主要问题是:为什么

您需要一个持久的默认值吗?在这种情况下,触发器将是更好的选择。。。或者,您可以直接使用带有计算值的insert语句。恐怕您将计算列和默认约束的概念混为一谈。无法更改计算列


如果您想在每次从该表获取数据时计算该值,最好使用视图或iTVF,您只需将所需的值连接到结果集。

如果您所说的是,如果表B中的值与主表a中的值匹配,并且B中没有匹配值,则需要表B中的值,使用文字作为默认值,请尝试以下操作:

挑选 银行 合并从ATM机中选择货币,其中货币=A。货币“NoMoney”作为“类型” 从…起 自动取款机 哪里

如果[Money]的select返回null,则将使用文字“NoMoney”


如果需要,您可以在合并的两侧都有一个select,右边不必是文字。

不要使用IIF开头。你想做什么?我有一个列,它必须根据另一个表中的值自动填充正确的值。表之间有连接。表B存储FK和表A PK。无论如何,这不是IIF的限制,该语句没有意义。这是CTE的一部分吗?为什么在CTE中使用IIF?如果要组合表中的值,请使用联接。这个表达式毫无意义。这个代码段中没有A表和B表。在查询中,用于定义别名或CTE,这意味着银行是CTE。错误本身非常清楚:IIF意味着从两个值中选择一个。使用在中返回多个值的查询只是一个错误。如果把[银行]用作。。。指向计算列。OP在一条注释中告诉我们,我需要select子句作为列Bank的默认值。我认为整个问题都是误导性的…谢谢你的解决方案,在阅读了你的“为什么”部分后,我决定删除本专栏,并用另一个工具解决它。非常感谢。@Pomme这听起来是最好的决定:-快乐编码!
CREATE  TABLE tblA (ID INT IDENTITY
                   ,SomeValue VARCHAR(100)
                   ,[Test] AS IIF(SomeValue IS NOT NULL,dbo.GetMyComputedColumn(SomeValue),'Default if null'));
GO

INSERT INTO tblA(SomeValue) VALUES('Test');
INSERT INTO tblA(SomeValue) VALUES(NULL);

SELECT * FROM tblA;
ID  SomeValue   Test
1   Test        wanted
2   NULL        Default if null