【问题标题】:Expression evaluator in sql query SELECTsql查询SELECT中的表达式求值器
【发布时间】:2015-08-21 07:53:43
【问题描述】:

我有这个问题

Declare @q varchar(255) = 'A+B'

Select
A, -- 1
B, -- 2
C,
Evaluate(@q) MySum -- 3
From tbl_temp

假设@q 也是来自 tbl_temp 的列

是否有任何方法 sql 可以做类似的事情?

我想到了一个接受表达式和列的函数。只是问有没有比这更好的方法。

任何帮助或建议将不胜感激。

谢谢

【问题讨论】:

    标签: sql sql-server tsql sqlclr


    【解决方案1】:

    基本答案是否定的。没有简单的方法可以做到这一点。一般来说,如果你有这样的表达式,那么你会使用动态 SQL 来解析它们。而且,您不能在函数中使用动态 SQL。

    这为您留下了两个基本选择。第一种是使用您自己的解析例程,可能在 CLR(用外部语言编写)中。如果您确实需要此功能,这是一种可行的方法。

    第二种是使用允许在函数中使用的存储过程之一:xp_cmdshell。注意:由于安全问题和特殊权限,不建议将此存储过程用作一般解决方案。此外,获取从存储过程计算的值需要一些技巧(本质上是将结果回显到预定义的表变量中)。

    【讨论】:

      【解决方案2】:

      您可以创建 CLR 函数来评估表达式:

      [Microsoft.SqlServer.Server.SqlFunction(DataAccess=DataAccessKind.Read)]
      public static object Evaluate(SqlString expression, SqlString values)
      {
          string[] variables = values.Value.Split(',');
      
          Dictionary<string, string> vars = new Dictionary<string, string>();
      
          foreach(string var in variables)
          {
              string[] varAndValue = var.Split('=');
      
              vars.Add(varAndValue[0], varAndValue[1]);
          }
      
          string expr = expression.Value;
      
          foreach(string var in vars.Keys)
          {
              expr = expr.Replace(var, vars[var]);
          }
      
          using (SqlConnection connection = new SqlConnection("context connection=true"))
          {
              connection.Open();
              SqlCommand command = new SqlCommand(string.Format("SELECT {0}", expr), connection);
              object result = command.ExecuteScalar();
              return result;
          }
      }
      

      然后在sql中使用如下:

      declare @t table(A int, B int, Expr varchar(max))
      insert into @t(A,B,Expr)
      select 5,6, 'A+B' union all
      select 1,2, 'A*B' 
      
      select dbo.Evaluate(Expr, 'A=' + cast(A as varchar) + ',' + 'B=' + cast(B as varchar))
      from @t
      

      【讨论】:

        【解决方案3】:

        免责声明:我是项目的所有者Eval SQL.NET

        SQL 中没有“eval”方法,但是可以使用 Eval SQL.NET 库轻松完成。

        -- CREATE expression
        DECLARE @sqlnet SQLNET = SQLNET::New('A+B')
        
        -- EVALUATE expression from a table
        SELECT @sqlnet.SetValue('A', A).SetValue('B', B).Eval()
        FROM tbl_temp
        

        文档:Dynamically evaluate arithmetic operation and expression in SQL

        【讨论】:

          猜你喜欢
          • 2018-07-14
          • 2014-11-28
          • 1970-01-01
          • 2015-12-20
          • 2016-01-23
          • 1970-01-01
          • 1970-01-01
          • 2012-08-19
          • 1970-01-01
          相关资源
          最近更新 更多