【问题标题】:Conditionally branching in SQL based on the type of a variable根据变量的类型在 SQL 中进行条件分支
【发布时间】:2009-03-30 13:52:23
【问题描述】:

我从一个可以是整数或 nvarchar 的表中选择一个值。它存储为 nvarchar。我想有条件地调用一个函数,如果它是一个整数(也就是说,如果它可以转换成整数),它将转换这个值,否则我想选择不转换的nvarchar。

这是针对 SQL Server 2005 数据库的。

select case
    when T.Value (is integer) then SomeConversionFunction(T.Value)
    else T.Value
end as SomeAlias

from SomeTable T

请注意,我遇到问题的是“(整数)”部分。提前致谢。

更新

查看对 Ian 答案的评论。它解释了为什么和什么更好一点。感谢大家的想法。

【问题讨论】:

    标签: sql sql-server sql-server-2005 tsql


    【解决方案1】:
     select case
         when ISNUMERIC(T.Value) then T.Value 
         else SomeConversionFunction(T.Value)
     end as SomeAlias
    

    另外,您是否考虑过使用 sql_variant 数据类型?

    【讨论】:

    • ISNUMERIC 不起作用 如果它起作用:这不可能发生,因为一列只有一种数据类型
    • msdn.microsoft.com/en-us/library/ms173829.aspx -- "一种存储各种 SQL Server 支持的数据类型值的数据类型"
    • 伊恩击中了它的头部。我不需要存储两种不同的数据类型。相反,我只对可以转换的数字感兴趣。这就是我想要显示的内容以及如何显示它的全部内容。如果它是一个 int,则需要将其转换为其对应的值。如果它是一个字符串,我只是显示它。
    • 另外,感谢有关 sql_variant 的提示。我一定会调查的。干杯!
    • 当我可以在 SQL 中使用 VB 时,为什么还要使用它?按照这个逻辑,我为什么不在云中创建一个服务,我可以调用它来检查它是否可以解析成整数?这样我就使用了一大堆不需要的技术。
    【解决方案2】:

    结果集的每一列只能有一个与之关联的类型,如果第一行转换为整数并且后面有字符串,则会出错:

    消息 245,第 16 级,状态 1,第 1 行 将 nvarchar 值 'word' 转换为数据类型 int 时转换失败。

    试试这个看看:

    create table  testing
    (
    strangevalue   nvarchar(10)
    )
    
    insert into testing values (1)
    insert into testing values ('word')
    select * from  testing
    
    select
        case
            when ISNUMERIC(strangevalue)=1 THEN CONVERT(int,strangevalue)
            ELSE strangevalue
         END
    FROM testing
    

    最好的办法是返回两列:

    select
        case
            when ISNUMERIC(strangevalue)=1 THEN CONVERT(int,strangevalue)
            ELSE NULL
         END AS StrangvalueINT
        ,case
            when ISNUMERIC(strangevalue)=1 THEN NULL
            ELSE strangevalue
         END AS StrangvalueString
    FROM testing
    

    或者您的应用程序可以测试数字并进行特殊处理。

    【讨论】:

      【解决方案3】:

      你不能有一个有时是整数,有时是字符串的列。返回字符串并在客户端代码中使用 int.TryParse() 进行检查。

      【讨论】:

        【解决方案4】:

        ISNUMERIC。但是,它接受 +、- 和小数,因此需要做更多的工作。

        但是,您不能同时将列作为两种数据类型:您需要 2 列。

        我建议您在客户中处理此问题或使用ISNUMERIC replacement

        【讨论】:

        • sql_variant 允许使用不同的类型,包括 nvarchar 和 int。
        【解决方案5】:

        IsNumeric 将助您一臂之力。然后你可以添加一些进一步的代码来检查它是否是一个整数

        例如:

        select top 10 
            case 
                when isnumeric(mycolumn) = 1 then 
                    case 
                        when convert(int, mycolumn) = mycolumn then
                            'integer'
                        else
                            'number but not an integer'
                    end
                else 
                    'not a number'
            end 
        from mytable
        

        【讨论】:

        • 这只会告诉你类型:而不是实际值,因为一列只有一种数据类型,所以不会发生
        • 我不相信这会奏效。当它尝试 CONVERT(INT, mycolumn) 时,如果该列实际上是小数,则会导致错误。
        • gbn:这只是示例代码,您可以将我编写的文本值替换为实际值本身(以及您希望默认值的任何值)。 Tom H:将 float 转换为 int 不会导致错误,它只会截断小数位
        【解决方案6】:

        为了澄清其他一些答案,您的 SQL 语句不能在一列中返回不同的数据类型(看起来其他答案是说您不能在一列中存储不同的数据类型 - 你的都是严格的表示)。

        因此,如果您使用 ISNUMERIC 或其他函数,则该值将被转换为表中的字符串,如果选择了其他字符串,则无论如何都会返回该字符串。

        如果您只选择一个值,那么它可以返回一个字符串或一个数字,但是您的前端代码需要能够返回不同的数据类型。

        【讨论】:

          【解决方案7】:

          只是向其他一些 cmets 添加关于无法在同一列中返回不同数据类型的内容......数据库列应该知道它们持有什么数据类型。如果他们不这样做,那应该是一个很大的危险信号,表明您在某个地方存在设计问题,这几乎可以保证将来会令人头疼(比如这个)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-08-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-02-09
            • 1970-01-01
            • 2023-02-03
            • 1970-01-01
            相关资源
            最近更新 更多