【问题标题】:Simplify multi true or false combined conditions简化多个真假组合条件
【发布时间】:2018-06-02 00:57:02
【问题描述】:

问题是我想从 SQL 表中提取特定记录并根据用户权限显示它(这是 5 组合真假的情况)。有没有办法避免为组合 5 个权限的所有 true 或 false 情况编写 32 个单独的检查和 32 个单独的 SQL select 语句?

例如:

bool priv1 true|false;
bool priv2 true|false;
bool priv3 true|false;
bool priv4 true|false;
bool priv5 true|false;

if (priv1 && !priv2 && !priv3 && !priv4 && !priv5)
{
    string sql = "SELECT * FROM table WHERE priv='1'";
}

等等……

编辑:我想提一下,一个用户可以拥有多个权限,这是主要问题,也是我说 32 例的原因。

【问题讨论】:

  • 你能把权限组织成按位枚举标志吗? Similar to the example here
  • 这个问题用你使用的数据结构真的很难解决。考虑将您的权限放入数组、列表或字典中。然后创建另一个表示所需权限的列表。从那里很容易比较它们。不能用这样的自变量来做,除非你做了一些真的很奇怪的事情。
  • 如果您使用权限表(在您的数据库中),那么您只需添加用户名并从该表中获取用户权限。 (假设每个用户都已注册并分配给这些特权之一。在您的 c# 中,只需比较用户名并查看分配给哪个 priv,然后从那里继续您的工作。
  • 为什么在 DB 的表中显然只有一列 priv?它的数据类型是什么,priv的值背后的逻辑是什么?
  • 枚举方法可以相当容易地处理具有多个权限的用户。 msdn.microsoft.com/en-us/library/… 。从上面的示例中,对于同时拥有 priv 1 和 5 的人,查询应该是什么?根据您是要进行联合还是相交,您可以在不使用分支逻辑的情况下相当容易地处理查询中的逻辑。 SELECT * FROM table WHERE [按位比较] 就可以了,只要能以枚举标志格式组织数据中的用户权限和priv标志即可。请分享您的解决方案。谢谢!

标签: c# sql asp.net logic


【解决方案1】:

将您的特权值放入数组中!!如果你被当前的变量卡住了,你可以这样做:

bool[] privileges = new bool[] { priv1, priv2, priv3, priv4, priv4 };

一旦它们在那里,您就可以使用 LINQ 生成一个 IN 子句:

var list = privileges
    .Select
    ( 
        (p,i) => new
        { 
            Index = i + 1, //Need to add 1, since array is zero-based
            Value = p 
        } 
    )
    .Where
    ( 
        p => p.Value 
    )
    .Select
    ( 
        p => string.Format("'{0}'", p.Index)
    );

var sql = string.Format
    (
        "SELECT * FROM table WHERE priv IN ({0}) ",
        string.Join(",", list)
    );

这将为您提供这种格式的 SQL 字符串:

SELECT * FROM table WHERE priv IN ('1','2')

注意事项:

Why is SELECT * considered harmful?

Why avoid dynamic SQL?

【讨论】:

    【解决方案2】:

    好吧,我想我会在我自己弄清楚如何做之后回答这个问题,但真的感谢大家的建议。

    它只是纯 SQL:

    sql = "SELECT * from requestsTable WHERE priv IN (SELECT priv FROM privilegesTable WHERE userID=@userID)
    

    【讨论】:

      【解决方案3】:

      这将需要一些调整,但我认为它得到了这个想法。这基本上就是我在powershell中的做法

      function Evaluate-Priv {
        param([int]$p)
        return Get-Random -Minimum 0 -Maximum 2
      }
      
      [array]$privs = @()
      
      for($i = 1;$i -le 5;$i++){
        switch(Evaluate-Priv($i)) {
          1 { $privs += "$i," }
          default { continue }
        }
      }
      
      [string]$SqlCmd = @"
        SELECT * FROM t WHERE t.priv in ($privs)
      "@
      
      Write-Output $SqlCmd
      

      多次运行的结果:

      SELECT * FROM t WHERE t.priv in (2, 3, 4, 5,)
      SELECT * FROM t WHERE t.priv in (2, 4, 5,)
      SELECT * FROM t WHERE t.priv in (1, 4, 5,)
      

      【讨论】:

        猜你喜欢
        • 2011-05-12
        • 2012-05-28
        • 1970-01-01
        • 1970-01-01
        • 2021-02-10
        • 2013-12-25
        • 1970-01-01
        • 1970-01-01
        • 2020-08-14
        相关资源
        最近更新 更多