在数据库中存储和解析布尔表达式

时间:2010-11-15 11:30:11

标签: c# sql sql-server tsql

这是我上一个问题which design pattern is suitable for this workflow requirement?的后续问题。我想知道什么是在数据库中存储布尔表达式的最佳方法,然后在运行时对其进行评估而不需要太多努力。我有一个要求,即每个月末需要从屏幕上执行一组作业,并且决定是否可以执行作业取决于先前作业的结果。所以我应该能够在数据库中保存一个像E =(A或B)和(C或D)的表达式(可以是任何复杂的嵌套表达式)。这意味着如果A或B成功且C或D成功,则E可以运行。如何在数据库中表示并解析并在以后评估条件?

想这样做(尚未测试)
如果“工作E =(A和B)或(C和D)”。将其存储为表格中的树结构

JobId DependentJobId SuccessJobId FailureJobId
E        A             B             C              
E        C             D             0
E        D             1             0
E        B             1             0

这意味着“如果A成功,请检查B否则检查C”,“如果C成功则检查D”。进程从最高节点开始,没有“DependentJobId”并在叶节点处停止。我使用虚拟Job Ids“1”表示成功,使用“0”表示失败。如果叶节点为零,则允许作业运行。我不确定如何在T-sql中对此进行评估。我可能不得不使用递归函数。

使用的技术:ASP.NET 3.5,C#3.0,SQL Server 2008

4 个答案:

答案 0 :(得分:6)

您可以将表达式作为字符串存储在数据库中,然后使用一组自定义函数或现有引擎在运行时解析它们。为实现这一目标,我在之前的项目中使用了以下内容:

FLEE (Fast Lightweight Expression Evaluator)

Dynamic Linq

我想说动态Linq更容易实现,因为你基本上可以使用熟悉的Linq / C#语法构造一个where子句并在数据库中存储为字符串。我在项目中使用了FLEE,我想构建自己的简单查询语言,但是很多这些我现在可以通过使用Dynamic Linq来实现。

答案 1 :(得分:1)

在我看来,您正试图在表格中编写业务规则。我相信编写填充表的代码会更好地在存储过程中编写规则。存储过程可以从MSDB中选择作业的运行状态,运行日期等。如果存在不是SQL代理作业的条件,则结果可以存储在包含作业名称,作业状态和作业日期的表中。存储过程可以使用简单的变量赋值来检索所有值,然后使用TSQL Bitwise运算符处理业务逻辑语句。

& (Bitwise AND) (Transact-SQL) 
~ (Bitwise NOT) (Transact-SQL) 
| (Bitwise OR) (Transact-SQL) 
^ (Bitwise Exclusive OR) (Transact-SQL)

你的E =(A和B)或(C和D)的例子将成为

Select @E=(@A & @B) | (@C & @D)

尝试以下代码,看看它是否适用于您的业务规则。

declare @E bit
declare @Bit1 bit
declare @Bit2 bit
declare @Bit3 bit
declare @Bit4 bit
declare @Bit5 bit
SET @Bit1 = 1
SET @Bit2 = 0
SET @Bit3 = 1
SET @Bit4 = 'fALSE'
SET @Bit5 = 0

SELECT @Bit1, @Bit2, @Bit3, @Bit4, @Bit5

SELECT @Bit1 & @Bit2


 Select @E=(@Bit1 & @Bit2) | (@Bit3 & @Bit4)
 Select @E as [E value]

答案 2 :(得分:1)

Macros和RC_Cleland都有很好的答案。我唯一要补充的是利用Windows Workflow Foundation为处理要求编写工作流的可能性。

答案 3 :(得分:0)

我使用我在问题中提到的方法解决了它。虽然将业务规则放在表中并不好,但我需要一个快速但可维护的解决方案,所以我选择了这个。如果我将作业依赖项存储在表中,我可以轻松地对其进行更改,而无需更改生成后有用的代码。我编写了一个递归函数来遍历作业依赖图并确定结果。感谢您的所有回复。