Not able to cast nvchar as number

Christopher Jack 1,616 Reputation points
2021-01-22T15:33:01.517+00:00

Hi,

We have had some SQL thats been running for about a year and it has suddenly stopped working.

CAST(ISNULL(M.DEFINED_KEY1, 0) AS NUMERIC(9, 0)) AS [No_of_Cats]

It basically puts a 0 instead of null and then makes it numeric.

I have checked the column and all it has in it is nulls or integers.

Anyone got any idea why this would suddenly stop working?

The error im getting is

Error converting data type nvarchar to numeric.

The largest number in the field is 1100000, the smallest is 0 and Null is the only other type of value.

Developer technologies | Transact-SQL
SQL Server | Other
{count} votes

Accepted answer
  1. tibor_karaszi@hotmail.com 4,316 Reputation points
    2021-01-22T16:33:18.647+00:00

    "I have checked the column and all it has in it is nulls or integers."

    You might have checked the data visually, in that case you have garbage in the data which doesn't show up visually.

    The trick is to find those rows, and those rows only. Below show you how you can do that. In your WHERE clause, use IS NOT NULL so you don't return the rows which are NULL and also use TRY_CAST to find those that aren't convertible to int:

    DROP TABLE IF EXISTS #t
    
    CREATE TABLE #t(c1 int identity, c2 nvarchar(10))
    
    INSERT INTO #t(c2) VALUES ('1')
    INSERT INTO #t(c2) VALUES ('123')
    INSERT INTO #t(c2) VALUES (NULL)
    INSERT INTO #t(c2) VALUES ('12' + CHAR(9)) --Note that CHAR(9) is TAB
    
    --It looks like data is fine!
    SELECT * FROM #t
    
    --But conversion fails because of TAB
    SELECT c1, CAST(c2 AS int)
    FROM #t
    
    --How to find the failed rows, and those only?
    SELECT c1, c2
    FROM #t
    WHERE c2 IS NOT NULL
    AND TRY_CAST(c2 AS int) IS NULL
    
    1 person found this answer helpful.

3 additional answers

Sort by: Most helpful
  1. Guoxiong 8,206 Reputation points
    2021-01-22T15:40:54.337+00:00

    Make sure there is no empty string in the data. For example, the following CAST would fail:

    DECLARE @s nvarchar(20) = '';
    SELECT CAST(ISNULL(@s, 0) AS NUMERIC(9, 0));
    

    Msg 8114, Level 16, State 5, Line 2
    Error converting data type nvarchar to numeric.

    It is better to do this:

    DECLARE @s nvarchar(20) = '';
    SELECT CAST(ISNULL(NULLIF(@s, ''), 0) AS NUMERIC(9, 0));
    
    1 person found this answer helpful.

  2. Olaf Helper 47,441 Reputation points
    2021-01-22T15:58:40.7+00:00

    I have checked the column and all it has in it is nulls or integers.

    But the error messages says, the column is of type nvarchar. I guess, there is an "invisible" character in the data, like control chars (tab, CR, LF), which makes the implicit (!) conversion failing.
    You can try using the ISNUMERIC (Transact-SQL) function to find the faulty data.

    1 person found this answer helpful.

  3. Yitzhak Khabinsky 26,586 Reputation points
    2021-01-22T16:34:23.58+00:00

    I would suggest the following approach.
    Change CAST(...) to TRY_CAST(...)

    It will allow you to filter just questionable rows for analysis. After that you will be able to adjust the conversion/casting statement.

    SQL

    -- DDL and sample data population, start
    DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, DEFINED_KEY1 NVARCHAR(100) NULL);
    INSERT INTO @tbl (DEFINED_KEY1) VALUES
    (N''),
    (NULL),
    (N'1100000'),
    (N'0');
    -- DDL and sample data population, end
    -- all rows
    SELECT * 
     , TRY_CAST(ISNULL(M.DEFINED_KEY1, 0) AS NUMERIC(9, 0)) AS [No_of_Cats]
    FROM @tbl AS m;
    -- failing to convert
    ;WITH rs AS
    (
     SELECT * 
     , TRY_CAST(ISNULL(M.DEFINED_KEY1, 0) AS NUMERIC(9, 0)) AS [No_of_Cats]
     FROM @tbl AS m
    )
    SELECT * FROM rs
    WHERE [No_of_Cats] IS NULL;
    
    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.