2015-06-06 40 views
1

我有這個疑問表達評價者選擇

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

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

假設@q也從tbl_temp

列有沒有做這樣的事情,任何方法SQL?

我記得,接受表達式和列的函數。只是問是否有比這更好的方法。

任何幫助或建議,將不勝感激。

感謝

回答

0

最基本的答案是否定的。沒有簡單的方法來做到這一點。一般來說,如果你有這樣的表達式,那麼你會使用動態SQL來解析它們。而且,你不能在一個函數中使用動態SQL。

這給你留下了兩個基本選項。首先是使用您自己的解析例程,可能在CLR中(使用外部語言編寫)。如果你真的需要這個功能,這是一個可行的方法。

第二種是使用您允許在函數中使用的存儲過程之一:xp_cmdshell。注意:由於存在安全問題和特殊權限,建議不要將此存儲過程作爲通用解決方案。另外,從存儲過程中獲取值需要一些聰明(基本上將結果回顯到預定義的表變量中)。

1

您可以創建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 
1

免責聲明:我是這個項目的所有者Eval SQL.NET

SQL中沒有「eval」方法,但使用Eval SQL.NET Library可以輕鬆完成。

-- 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