【问题标题】:How to build a rules table in sql server如何在sql server中建立规则表
【发布时间】:2017-04-20 16:39:11
【问题描述】:

目前有很多业务规则在存储过程中被硬编码。想要探索设置规则表的选项,我们打算在其中键入所有业务规则并基于它执行存储过程。

虽然系统有点复杂,但这里提供了一个简单的版本。

Create table tblTest
(
    TranID int primary key not null,
    FName varchar(20) not null,
    Age int not null,
    Salary money not null,
    MaritalStatus char(1) not null
)

Insert into tblTest values (1, 'Alex', 26, '25000.00','Y')
Insert into tblTest values (2, 'Brenda', 25, '14500.00','Y')
Insert into tblTest values (3, 'Peter', 69, '50000.00','N')
Insert into tblTest values (4, 'Paul', 64, '74500.00','Y')

现在为了保持示例简单,我们假设业务规则如下: 1. 年龄 >=25,
2. 年龄 3. 薪水 > 15K

Create table tblBusRule
(
    RuleID int Primary key not null,
    ColName varchar(20) not null,
    Operator varchar(2) not null,
    ColValue varchar(10) not null,
    RuleOrder int not null
)

Insert into tblBusRule values (1, 'Age', '>=', '25', 1)
Insert into tblBusRule values (2, 'Age', '<', '65', 2)
Insert into tblBusRule values (3, 'Salary', '>', '15000.00', 3)

直接查询是这样的,它会单独输出记录 1 (Alex) 和 4 (Paul)。

Select * from tblTest
where 
        age >=25 and 
        age < 65 and 
        salary > '15000.00'

现在如何根据 tblBusRule 中提到的规则使这个动态化?

【问题讨论】:

    标签: sql-server-2008-r2 sql-server-2016


    【解决方案1】:

    使用stuff() with select ... for xml path ('') method of string concatenationsp_executesql

    declare @sql nvarchar(max), @where nvarchar(max);
    set @where = stuff((
      select '  and '+colname +' '+operator +' ' + colvalue+char(10)
        from tblBusRule
        order by RuleOrder
      for xml path (''), type).value('.','nvarchar(max)')
      ,1,6,'');
    
    set @sql = 'select * ' +char(10)+'from tblTest'+char(10)+'where '+@where;
    
    select @sql as CodeGenerated;
    exec sp_executesql @sql;
    

    rextester 演示:http://rextester.com/CGRF91788

    返回:

    +-------------------------+
    |      CodeGenerated      |
    +-------------------------+
    | select *                |
    | from tblTest            |
    | where Age >= 25         |
    |   and Age < 65          |
    |   and Salary > 15000.00 |
    +-------------------------+
    
    +--------+-------+-----+------------+---------------+
    | TranID | FName | Age |   Salary   | MaritalStatus |
    +--------+-------+-----+------------+---------------+
    |      1 | Alex  |  26 | 25000,0000 | Y             |
    |      4 | Paul  |  64 | 74500,0000 | Y             |
    +--------+-------+-----+------------+---------------+
    

    参考: - The curse and blessings of dynamic SQL - Erland Sommarskog

    【讨论】:

    • 感谢您的回答。只是想了解我们可以如何灵活地制作这个业务规则表。如果必须对不同的表应用规则,脚本将如何更改。我的意思是假设工资列在表 B 中。
    • @prasanth 。 . .好吧,它可以像您投入的工作量一样灵活...如果您想让规则适用于多个表,那么您可能应该确定哪些规则适用于哪些表,并检索适用于这些表的规则在您的查询中。
    • :) 好的,也许会将其作为一个单独的问题发布,示例结构和输出预计会更清晰。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2017-11-06
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 2011-03-17
    • 2013-08-15
    • 2011-06-04
    相关资源
    最近更新 更多