我已經創建了一個用戶定義的標量函數,輸入參數是用於評估和返回值的字符串 - 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
也許試試這樣的: 'declare @exp varchar(100);選擇@exp ='1 + 1 + 0 + 1 * 0 * 1 + 1 * 1 + 0'; select @exp = replace(REPLACE(@exp,'+','&'),'*','&') select @exp; exec('select'+ @ exp);' – LoztInSpace 2013-04-22 13:53:30
@LoztInSpace我不想使用「exec」語句,因爲我需要這樣做數百次。這是我最初的問題,因爲這個原因,我做了一個標量函數來執行行。另一種方法是創建一個LOOP並在其中執行動態SQL語句。 – gotqn 2013-04-22 14:33:02