Sql server 2012 T-SQL—布尔表达式字符串求值技术

Sql server 2012 T-SQL—布尔表达式字符串求值技术,sql-server-2012,execute,boolean-expression,Sql Server 2012,Execute,Boolean Expression,我需要填充“Value”字段,根据表达式的不同,“Value”字段可以是“0”或“1”false或true 以下是简单的数据: 1 1 * 1 + 1 NULL 2 0 + 0 NULL 3 1 + 0 * 0 NULL 4 0 * 1 NULL 5 0 * 1 * 1 NULL “表达式”字段的类型为nvarchar,包含条件和布尔运算符的结果。 因此,上述数据的格式如下: 1 TRUE AND TRUE OR TRUE N

我需要填充“Value”字段,根据表达式的不同,“Value”字段可以是“0”或“1”false或true

以下是简单的数据:

1   1 * 1 + 1   NULL
2   0 + 0       NULL
3   1 + 0 * 0   NULL
4   0 * 1       NULL
5   0 * 1 * 1   NULL
“表达式”字段的类型为nvarchar,包含条件和布尔运算符的结果。 因此,上述数据的格式如下:

1   TRUE AND TRUE OR TRUE     NULL
2   FALSE OR FALSE            NULL
3   TRUE OR FALSE AND FALSE   NULL
4   FALSE AND TRUE            NULL
5   FALSE AND TRUE AND TRUE   NULL
最后,“表达式”字段可以包含和/或多个TRUE和FALSE

正如我所说,我需要的是计算表达式的值——检查它是真是假

整个逻辑都在过程中,我可以为每一行构建动态sql并执行它, 但在我的实际情况中,我将有数百行,因此为每行创建循环并调用execute_sql听起来并不是一个好的解决方案


是否有任何内置函数可以帮助我计算这些字符串,因为我无法在过程中使用交叉应用。

为什么不在插入时而不是在查询时计算它?结果的一位开销与解析和执行查询的开销相比可能是值得的。您可以将其作为触发器yuk或具有更好的UDF的计算列来执行

我认为,几乎所有您需要做的就是将一些动态SQL链接到一些搜索和替换


如果组合的数量有限,另一种方法就是查找表达式减去空格等后的结果。

我创建了一个用户定义的标量函数,输入参数为求值字符串,返回值为-0或1 false或true。现在,我可以做的愿望交叉申请

以下是一些例子:

SELECT [dbo].[fn_XxCustom_EvaluateExpression] ('0')                 -- 0
SELECT [dbo].[fn_XxCustom_EvaluateExpression] ('1')                 -- 1
SELECT [dbo].[fn_XxCustom_EvaluateExpression] ('1*1')               -- 1
SELECT [dbo].[fn_XxCustom_EvaluateExpression] ('1+1')               -- 1
SELECT [dbo].[fn_XxCustom_EvaluateExpression] ('1*0')               -- 0
SELECT [dbo].[fn_XxCustom_EvaluateExpression] ('0+1*0*1+0*1+0')     -- 0
SELECT [dbo].[fn_XxCustom_EvaluateExpression] ('1+1+0+1*0*1+1*1+0') -- 1
我相信有一种更好的方法可以做到这一点,可能是使用反向波兰符号和递归CTE,但我没有时间尝试。无论如何,如果有人需要做类似的事情,这就是源代码:

IF  EXISTS (SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fn_XxCustom_EvaluateExpression]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
BEGIN
    DROP FUNCTION [dbo].[fn_XxCustom_EvaluateExpression]
END

GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION [dbo].[fn_XxCustom_EvaluateExpression]
(
    @Expression NVARCHAR(MAX)
)
RETURNS TINYINT
AS
BEGIN

    DECLARE @ExpressionValue TINYINT = 0

    IF LEN(@Expression) > 0 AND @Expression IS NOT NULL
    BEGIN

        -- Checking if this is expression 
        IF CHARINDEX('+', @Expression) = 0 AND CHARINDEX('*', @Expression) = 0 
            BEGIN
                SET @ExpressionValue = CAST(@Expression AS TINYINT)
            END
        ELSE
            BEGIN

                -- Checking if the expression is computed (contains both '*' and '+')
                IF CHARINDEX('+', @Expression) > 0 AND CHARINDEX('*', @Expression) > 0
                    BEGIN 

                        DECLARE @ExpressionsTable TABLE
                        (
                             ExpressionID INT IDENTITY(1,1)
                            ,Expression NVARCHAR(MAX)
                            ,ExpressionValue TINYINT
                        )

                        DECLARE @XML XML = N'<r><![CDATA[' + REPLACE(@Expression, '+', ']]></r><r><![CDATA[') + ']]></r>'

                        -- Populate the table with simple expressions (expression which only contains '+' or '*' is simple)
                        INSERT INTO @ExpressionsTable (Expression)
                        SELECT DISTINCT RTRIM(LTRIM(T.c.value('.', 'nvarchar(250)')))
                        FROM @xml.nodes('//r') T(c)

                        -- Creating a simple expressions with result values 
                        UPDATE @ExpressionsTable
                        SET ExpressionValue = IIF(CHARINDEX('+', Expression) = 0 AND CHARINDEX('*', Expression) = 0 , Expression, IIF(CHARINDEX('+', Expression) > 0,IIF(CHARINDEX('1', Expression) > 0, 1, 0),IIF(CHARINDEX('0', Expression) > 0, 0, 1)))

                        -- Evaluating the final expression
                        SET @ExpressionValue = IIF(CHARINDEX('1', SUBSTRING((SELECT '+' + CAST(ExpressionValue AS VARCHAR(1)) FROM @ExpressionsTable FOR XML PATH('')),2,4000)) > 0, 1, 0)

                    END
                ELSE
                -- Checking the type of the simple expression (does it contains '+' or '*')
                    BEGIN
                        SET @ExpressionValue = IIF(CHARINDEX('+', @Expression) > 0,IIF(CHARINDEX('1', @Expression) > 0, 1, 0),IIF(CHARINDEX('0', @Expression) > 0, 0, 1))
                    END
            END
    END

    RETURN @ExpressionValue

END
GO

因为每个值0或1都是复杂的select语句和检查的结果。您可能需要更新问题和示例输入/输出列表,尤其是标题。我现在真的不清楚你有什么或你在追求什么。我已经设法独自找到了问题。无论如何+1,谢谢你试图帮助我。也许可以试试这样的东西:declare@exp varchar100;选择@exp='1+1+0+1*0*1+1*1+0';选择@exp=replaceREPLACE@exp“+”、“&”、“*”、“&”选择@exp;exec'select'+@exp@LoztInSpace我不想使用exec语句,因为我需要这样做数百次。这是我的第一个问题,正因为如此,我创建了一个标量函数,它将对行执行。另一种方法是创建一个循环,并在其中执行动态SQL语句。