如何在动态sql中使用Isnumeric?

时间:2016-02-23 19:16:07

标签: sql sql-server sql-server-2012

我需要知道如何从varform数据类型的outputformula列中获取数值。

我在动态sql查询中使用此outputformula列来执行数学计算。

我有以下代码表和select查询来获取值。

Create table #table1
(
IDNUM  int,
outputformula  varchar(60)
)

insert into #table1
values 
(1, '67349.000 +78343.000'),
(2, 'a +78343.000'),
(3, '45783.00+b'),
(4, '6152.000 +1524.000'),
(5, 'cda +7151.000'),
(6, '67349.000 +78343.000')

    Select outputformula from #table1 where ISNUMERIC(outputformula) =1

当我执行代码时,我得不到任何值是否有办法只获得除列中字母表之外的数值的输出....

我应该将输出列设为

 67349.000 +78343.000
 6152.000 +1524.000
 67349.000 +78343.000

3 个答案:

答案 0 :(得分:1)

不幸的是,ISNUMERIC没有评估公式。您可以尝试在SQL函数中编写自己的简单解析器,但函数不允许任何类型的错误处理,因此当您尝试评估其中一个非数字方程时,您会遇到问题

您最好的选择可能是使用您用来评估这些方程式的任何内容来执行此任务 - 我认为这是在某种前端。

由于您没有使用前端,因此我可以提出最佳的直接SQL方法。首先,创建一个可以评估仅数字方程的存储过程。这可能会更好,但不幸的是,函数不允许TRY..CATCH块,这对于处理非数字方程式至关重要。以下是此类存储过程的示例:

CREATE PROCEDURE dbo.Check_Dynamic_Formula
    @formula VARCHAR(60),
    @result DECIMAL(10, 4) OUTPUT
AS
BEGIN
    DECLARE
        @sql NVARCHAR(100)

    BEGIN TRY
        SELECT @sql = 'SELECT @inner_result = ' + @formula

        EXEC sp_executesql @sql, N'@inner_result DECIMAL(10, 4) OUTPUT', @inner_result = @result OUTPUT
    END TRY
    BEGIN CATCH
        SELECT @result = NULL
    END CATCH
END

一旦你有了这个,你可以设置CURSOR一次一行地通过你的表(这就是为什么标量函数会好得多,因为你可以避免CURSOR )。检查表中每行的输出变量。如果它是NULL,则存储过程无法对其进行评估。

一些重要的警告......

在某些情况下,评估会无意中成为数字 - 请参阅@Sean Lange对您问题的评论。

重要这非常容易受到注射。我不会针对任何可供用户生成的数据运行此操作。例如,如果您有用户输入公式,那么他们可以进行SQL注入攻击。

最后,如果TRY..CATCH块中出现任何其他错误,它将使其看起来好像该行是非数字的。我们指望代码未能证明它是非数字的,这是一种脆弱的方法。任何错误都可能给你带来假阴性。

答案 1 :(得分:1)

如果所有字符串的格式为{token1} blank {token2},则一种方法是在数据库中定义Split函数并使用以下代码:

SQL ISNUMERIC

但是,您应该考虑java.lang.IncompatibleClassChangeError: Found interface org.springframework.test.context.TestContext, but class was expected函数有一些限制并提供some false positives

进行更具体的数字检查的一种方法是使用TRY_CONVERT函数。

答案 2 :(得分:0)

ISNUMERIC只返回1或0.在这种情况下,您要求报告返回outputformula列中的任何数字,但由于您将该字段声明为VARCHAR(60),因此返回0结果。

查看此其他帖子,了解您的问题的可能答案。

Query to get only numbers from a string

希望这有帮助!