T-sql - determine if value is integer

后端 未结 20 2164
情深已故
情深已故 2020-11-30 12:11

I want to determine if a value is integer (like TryParse in .NET). Unfortunatelly ISNUMERIC does not fit me because I want to parse only integers a

相关标签:
20条回答
  • 2020-11-30 12:48

    I have a feeling doing it this way is the work of satan, but as an alternative:

    How about a TRY - CATCH?

    DECLARE @Converted as INT
    DECLARE @IsNumeric BIT
    
    BEGIN TRY
        SET @Converted = cast(@ValueToCheck as int)
        SET @IsNumeric=1
    END TRY
    BEGIN CATCH
        SET @IsNumeric=0
    END CATCH
    
    select IIF(@IsNumeric=1,'Integer','Not integer') as IsInteger
    

    This works, though only in SQL Server 2008 and up.

    0 讨论(0)
  • 2020-11-30 12:50

    This work around with IsNumeric function will work:

    select * from A where ISNUMERIC(x) =1 and X not like '%.%'

    or Use

    select * from A where x **not like** '%[^0-9]%'

    0 讨论(0)
  • 2020-11-30 12:51

    Necromancing.
    As of SQL-Server 2012+, you can use TRY_CAST, which returns NULL if the cast wasn't successful.

    Example:

    DECLARE @foo varchar(200)
    SET @foo = '0123' 
    -- SET @foo = '-0123' 
    -- SET @foo = '+0123' 
    -- SET @foo = '+-0123' 
    -- SET @foo = '+-0123' 
    -- SET @foo = '.123' 
    -- SET @foo = '1.23' 
    -- SET @foo = '.' 
    -- SET @foo = '..' 
    -- SET @foo = '0123e10' 
    
    SELECT CASE WHEN TRY_CAST(@foo AS integer) IS NULL AND @foo IS NOT NULL THEN 0 ELSE 1 END AS isInteger 
    

    This is the only really reliable way.

    Should you need support for SQL-Server 2008, then fall back to Sam DeHaan's answer:

    SELECT CASE WHEN ISNUMERIC(@foo + '.e0') = 1 THEN 1 ELSE 0 END AS isInteger 
    

    SQL-Server < 2012 (aka 2008R2) will reach end of (extended) support by 2019-07-09.
    At this time, which is very soon, support for < 2012 can be dropped.
    I wouldn't use any of the other hacks at this point in time anymore.
    Just tell your frugal customers to update - it's been over 10 years since 2008.

    0 讨论(0)
  • 2020-11-30 12:52

    In his article Can I convert this string to an integer?, Itzik Ben-Gan provides a solution in pure T-SQL and another that uses the CLR.

    Which solution should you choose?

    Is the T-SQL or CLR Solution Better? The advantage of using the T-SQL solution is that you don’t need to go outside the domain of T-SQL programming. However, the CLR solution has two important advantages: It's simpler and faster. When I tested both solutions against a table that had 1,000,000 rows, the CLR solution took two seconds, rather than seven seconds (for the T-SQL solution), to run on my laptop. So the next time you need to check whether a given string can be converted to an integer, you can include the T-SQL or CLR solution that I provided in this article.

    If you only want to maintain T-SQL, then use the pure T-SQL solution. If performance is more important than convenience, then use the CLR solution.

    The pure T-SQL Solution is tricky. It combines the built-in ISNUMERIC function with pattern-matching and casting to check if the string represents an int.

    SELECT keycol, string, ISNUMERIC(string) AS is_numeric,
      CASE
        WHEN ISNUMERIC(string) = 0     THEN 0
        WHEN string LIKE '%[^-+ 0-9]%' THEN 0
        WHEN CAST(string AS NUMERIC(38, 0))
          NOT BETWEEN -2147483648. AND 2147483647. THEN 0
        ELSE 1
      END AS is_int
    FROM dbo.T1;
    

    The T-SQL part of the CLR solution is simpler. You call the fn_IsInt function just like you would call ISNUMERIC.

    SELECT keycol, string, ISNUMERIC(string) AS is_numeric,
      dbo.fn_IsInt(string) AS is_int
    FROM dbo.T1;
    

    The C# part is simply a wrapper for the .NET's parsing function Int32.TryParse. This works because the SQL Server int and the .NET Int32 are both 32-bit signed integers.

    using System;
    using System.Data.SqlTypes;
    
    public partial class UserDefinedFunctions
    {
        [Microsoft.SqlServer.Server.SqlFunction]
        public static SqlBoolean fn_IsInt(SqlString s)
        {
            if (s.IsNull)
                return SqlBoolean.False;
            else
            {
                Int32 i = 0;
                return Int32.TryParse(s.Value, out i);
            }
        }
    };
    

    Please read Itzik's article for a full explanation of these code samples.

    0 讨论(0)
  • 2020-11-30 12:56

    Had the same question. I finally used

    where ATTRIBUTE != round(ATTRIBUTE)
    

    and it worked for me

    0 讨论(0)
  • 2020-11-30 12:57

    Sometimes you don't get to design the database, you just have to work with what you are given. In my case it's a database located on a computer that I only have read access to which has been around since 2008.

    I need to select from a column in a poorly designed database which is a varchar with numbers 1-100 but sometimes a random string. I used the following to get around it (although I wish I could have re designed the entire database).

    SELECT A from TABLE where isnumeric(A)=1
    
    0 讨论(0)
提交回复
热议问题