具有针对计算列的多个案例陈述的IIF

时间:2018-12-05 10:48:19

标签: sql-server tsql

我正在尝试将其添加为公式(计算列),但收到一条错误消息,指出它无效。

任何人都可以看到以下公式有什么问题吗?

IIF
(
    select * from Config where Property = 'AutomaticExpiry' and Value = 1,
    case when [ExpiryDate] IS NULL OR sysdatetimeoffset()<[ExpiryDate] then 1 else 0 end,
    case when [ExpiryDate] IS NULL then 1 else 0 end
)

3 个答案:

答案 0 :(得分:3)

来自BOL:ALTER TABLE computed_column_definition

  

computed_column_expression是定义以下项的值的表达式   计算列。计算列是虚拟列,不是   物理上存储在表中,但是根据以下表达式计算得出的:   使用同一表中的其他列。例如,计算列   可以具有以下定义:成本AS价格*数量。表达式可以是   非计算的列名,常量,函数,变量以及任何   由一个或多个操作员连接的这些的组合。   表达式不能是子查询,也不能包含别名数据类型。

答案 1 :(得分:1)

包装登录功能。像这样:

CREATE FUNCTION [dbo].[fn_CustomFunction]
(
    @ExpireDate DATETIME2
) 
RETURNS BIT
AS
BEGIN;

    DECLARE @Value BIT = 0;

    IF EXISTS(select * from Config where Property = 'AutomaticExpiry' and Value = 1)
    BEGIN;
        SET @Value = IIF (sysdatetimeoffset()< @ExpireDate, 1, 0)
        RETURN @value;
    END;

    RETURN IIF(@ExpireDate IS NULL, 1, 0);

END;

GO

--DROP TABLE IF EXISTS dbo.TEST;

CREATE TABLE dbo.TEST
(
    [ID] INT IDENTITY(1,1)
   ,[ExpireDate] DATETIME2
   ,ComputeColumn AS [dbo].[fn_CustomFunction] ([ExpireDate])
)

GO

INSERT INTO dbo.TEst (ExpireDate)
VALUES ('2019-01-01')
      ,('2018-01-01')
      ,(NULL);

SELECT *
FROM dbo.Test;

答案 2 :(得分:0)

您正在尝试做某事,我们不太确定-您犯了一个典型的XY问题错误。您有一些任务,例如“如果prefs表中已启用,则执行自动登录到期”,并且ve设计了这个坏的解决方案(使用计算列/ IIF),并寻求帮助来了解为什么它坏了。这没有解决实际的核心问题。

从当前状态过渡到要解决问题的状态时,可以考虑:

以查看:

CREATE VIEW yourtable_withexpiry AS
SELECT 
  *, 
  CASE WHEN [ExpiryDate] IS NULL OR config.[Value] = 1 AND SysDateTimeOffset() < [ExpiryDate] THEN 1 ELSE 0 END AS IsValid
FROM 
  yourtable
  LEFT JOIN 
  config
  ON config.property = 'AutomaticExpiry' 

作为触发器:

CREATE TRIGGER trg_withexpiry ON yourtable 
AFTER INSERT OR UPDATE  
AS  
    IF NOT EXISTS(select * from Config where Property = 'AutomaticExpiry' and Value = 1)
    RETURN;

    UPDATE yourtable SET [ExpiryDate] = DATE_ADD(..some current time and suitable offset here..)
    FROM yourtable y INNER JOIN inserted i ON y.pk = i.pk;

END; 

但是说实话,您应该在前端应用程序中执行此操作。它应该负责读取/写入会话数据并保持最新状态,并在超时的情况下将其赶出用户等。使用数据库在很大程度上将业务逻辑/决策处理放入系统中不用担心。.

让您的前端语言实现一个代码,该代码可以在某些常规事件(例如页面导航或其他活动)上查找用户信息,并仅在未超过有效日期的情况下刷新该活动的有效日期。如果您想让人们永远活跃(或任何其他方式)的话,如果将过期设置为null,也可以肯定使事情保持有效。