如何计算字符串语句

时间:2017-02-16 06:25:11

标签: tsql

给定一个字符串组合,它是一个计算语句,我如何得到结果,在这种情况下是下面代码中的列cal。 我知道我可以使用案例,但有没有直接的方法来进行计算?

    create table tl_test
    (
            cl1 int
    )

    create table tl_test2
    (
            cl1 char(1)
    )
    insert into tl_test values (21), (43), (13), (36), (41)
    insert into tl_test2 values ( '+'), ('-'), ('*'), ('/')

    select *,
    cast(c1 as varchar) + f1 
    + cast(c2 as varchar) + f2 
    + cast(c3 as varchar) + f3 
    + cast(c4 as varchar) + f4 
    + cast(c5 as varchar) as cal
    from(
    SELECT A.cl1 as c1, f1.cl1 as f1,  b.cl1 as c2,f2.cl1 as f2, C.cl1 as c3, f3.cl1 as f3, D.cl1 as c4, f4.cl1 as f4,  E.cl1 as c5
    FROM TL_TEST A
    CROSS JOIN TL_TEST2 f1
    CROSS JOIN TL_TEST B
    CROSS JOIN TL_TEST2 f2
    CROSS JOIN TL_TEST C
    CROSS JOIN TL_TEST2 f3
    CROSS JOIN TL_TEST D
    CROSS JOIN TL_TEST2 f4
    CROSS JOIN TL_TEST E
    )a
    WHERE c1 != c2
    and c1 != c3
    and c1 != c4
    and c1 != c5
    and c2 != c3
    and c2 != c4 
    and c2 != c5
    and c3 != c4
    and c3 != c5
    and c4 != c5

2 个答案:

答案 0 :(得分:0)

您可以将 cal 列的结果存储在字符串中,然后使用EXEC计算答案。

DECLARE @sql NVARCHAR(MAX) = 'SELECT ' + (SELECT TOP 1 cal FROM result)
EXEC(@sql)

答案 1 :(得分:0)

阅读this related thread,特别是Erland Sommarskog的答案。

抱歉,无法在纯 ad-hoc T-SQL 中执行此操作。

可能的解决方法:

1)您可以使用动态SQL,它有一个缺陷:您的示例将计算为INT s

DECLARE @cmd VARCHAR(100)='SELECT (' + '21*41-36 / 13+43' /*Your formula coming from somewhere*/ + ')';
EXEC(@cmd);

结果902

2)你可以使用XML隐式能力来计算这个

SELECT CAST('' AS XML).value('21*41-36 div 13+43','float') 
hint: "/" must be replaced with " div "

结果901.23077

这是一个很小的问题,XML类型的.value()知道表达式。可以动态地从表的列中引入值(sql:column("ColumnName")),但表达式必须是文字。

3)你可以包括.Net - 代码作为汇编(CLR函数)。

Conclusio

对不起,没有什么好事......

如果您需要精确的结果,则应在动态创建的SQL中使用XML方法。

更新工作示例

DECLARE @tbl TABLE(ID INT IDENTITY,SomeFormula VARCHAR(100));
INSERT INTO @tbl(SomeFormula) VALUES
 ('1+2')
,('21*41-36/13+43')
,('(1+3)*4')
,('3.6 div (2.5-1)');

DECLARE @cmd VARCHAR(MAX)=
(
    SELECT 'DECLARE @x XML=CAST('''' AS XML);' +
    STUFF
    (
      (
        SELECT ' UNION ALL SELECT ' + CAST(ID AS VARCHAR(MAX)) + ' AS ID, @x.value(''' + REPLACE(SomeFormula,'/',' div ') + ''',''float'')'
        FROM @tbl
        FOR XML PATH('')
      ),1,11,''
    )
);
PRINT @cmd;
EXEC (@cmd);

这是生成的语句

DECLARE @x XML=CAST('' AS XML);
          SELECT 1 AS ID, @x.value('1+2','float') 
UNION ALL SELECT 2 AS ID, @x.value('21*41-36 div 13+43','float') 
UNION ALL SELECT 3 AS ID, @x.value('(1+3)*4','float') 
UNION ALL SELECT 4 AS ID, @x.value('3.6 div (2.5-1)','float')

这是结果

ID  
1   3
2   901,23077
3   16
4   2,4