代码之家  ›  专栏  ›  技术社区  ›  Philip

计算列有多个Case语句的IIF

  •  0
  • Philip  · 技术社区  · 7 年前

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

    有人知道下面的公式有什么问题吗?

    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 回复  |  直到 7 年前
        1
  •  3
  •   Denis Rubashkin    7 年前

    来自BOL: ALTER TABLE computed_column_definition

    computed_column_表达式是一个定义 计算列。计算列是一个虚拟列,它不是 物理存储在表中,但根据 使用同一表中的其他列。例如,计算列 可以定义为:成本为价格*数量。表达式可以是 未计算的列名、常量、函数、变量和任何 由一个或多个运算符连接的这些值的组合。 这个 表达式不能是子查询或包含别名数据类型。

        2
  •  1
  •   gotqn user3521065    7 年前

    包装登录功能。像这样的:

    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;
    
        3
  •  0
  •   Caius Jard    7 年前

    你想做点什么,我们不太确定-你犯了一个典型的XY问题错误。。您有一些任务,比如“在prefs表中启用时实现自动登录到期”,并且您设计了这个中断的解决方案(使用计算列/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; 
    

    但老实说,你应该在你的前端应用程序中这样做。它应该负责读/写会话数据,保持最新状态,如果用户超时,则将其踢出。。在很大程度上,使用数据库就是将业务逻辑/决策处理放入一个不应该与之相关的系统中。。

    让您的前端语言实现一个代码,该代码在某些常规事件(如页面导航或其他活动)上查找用户信息,并作为活动的结果刷新到期日期,前提是未传递到期日期。当然,如果你想让人们永远活跃(或者其他什么),那么如果expiry设置为null,那么也要保持这个东西的有效性