如何在SQLite触发器中实现If语句?

时间:2015-05-25 06:47:49

标签: sql linq sqlite

我们在SQLite数据库中定义了一个自引用关系......

Create Table Categories{
    Id INTEGER PRIMARY KEY,
    Name TEXT NOT NULL CHECK(length(Text) > 0),
    ParentId INTEGER References Categories(Id),
    IsSelected BOOL
};

我们正尝试在IsSelected字段上设置触发器,以自动在层次结构中传播值。

将值设置为True时,很容易。我们只需设置触发器将其父级设置为True,然后对其父级执行相同操作,向上移动层次结构直到它到达根目录。

但是,当我们将其设置为False时,该逻辑不适用,因为可能有另一个兄弟记录被更改仍然是真的,因此其父级仍然是真的。

那么如何在触发器中执行以下操作?注意,这显然是SQL,C#和LINQ的荒谬混合体,但它说明了我试图做的事情。

CREATE TRIGGER T_Categories_IsSelectedChanged
UPDATE OF IsSelected ON Categories
BEGIN
    if(new.IsSelected)
        Update Categories Set IsSelected = True Where Id = old.ParentId;
    else
    {
        void isSiblingSelected = Categories
            .Where(c => c.ParentId = old.ParentId)
            .Any(c => c.IsSelected);

        UPDATE Categories 
        SET IsSelected = isSiblingSelected
        WHERE Id = old.ParentId;
    }
END

现在技术上已经是'其他'条款适用于这两种情况。 If更像是一个短路,但也许我可以做这样的事情......

Update Categories
SET IsSelected = (
    SELECT EXISTS(SELECT 1 FROM Categories
    WHERE IsSelected = True 
    AND ParentId = old.ParentId
    LIMIT 1))
Where ID = old.ParentId;

......但这只是一个猜测。我是在正确的轨道上吗?

2 个答案:

答案 0 :(得分:0)

您可以参考http://www.sqlite.org/lang_expr.html#case

我不确定,但你的代码可能就像,

CREATE TRIGGER T_Categories_IsSelectedChanged
UPDATE OF IsSelected ON Categories
BEGIN
case when new.isSelected then
    Update Categories Set IsSelected = True Where Id = old.ParentId;
else
    Update Categories Set IsSelected = Categories
        .Where(c => c.ParentId = old.ParentId)
        .Any(c => c.IsSelected);
END

答案 1 :(得分:0)

CASE不是声明;你只能在表达式中使用它。

但是,触发器具有WHEN clause,它采用任意SQL表达式:

CREATE TRIGGER T_Categories_IsSelectedChanged_true
AFTER UPDATE OF IsSelected ON Categories
FOR EACH ROW
WHEN new.IsSelected
BEGIN
    UPDATE Categories
    SET IsSelected = 1
    WHERE Id = old.ParentId;
END;

CREATE TRIGGER T_Categories_IsSelectedChanged_false
AFTER UPDATE OF IsSelected ON Categories
FOR EACH ROW
WHEN NOT new.IsSelected
BEGIN
    UPDATE Categories 
    SET IsSelected = (SELECT IFNULL(MAX(IsSelected), 0)
                      FROM Categories
                      WHERE ParentId = old.ParentId)
    WHERE Id = old.ParentId;
END;