SQL Error (245): Conversion failed when converting the nvarchar value '50%' to data type int

2.5k views Asked by At

Definitions

[Rec_Num] [int] IDENTITY(1,1) NOT NULL,
[Pro_PCT] [nvarchar](50) NULL
[Max_Off] [nvarchar](50) NULL
[IsExceeds]  AS (CONVERT([int],[Pro_PCT])-CONVERT([int],replace([Max_Off],'%','')))

Data

enter image description here

Query

select top 200 * from dbo.FO_Entry
where isexceeds>0
order by Rec_Num desc

The above query works fine and shows the data. But when I change the top 200 to 201 then it throws the below error.

enter image description here

If I run the Top 201 statement 2 or three times then it shows the data. Again if I change the Top 201 to To 202 then again the error popsup.

Any suggestion will be very much helpful.

Note:- Problem occurs when I use where IsExceeds>0 condition. Also I believe that the IsExceeds calculation may be causing this issue.

1

There are 1 answers

0
Thom A On BEST ANSWER

The real problem is your design, fix that, and the problem goes away. Your column Pro_PCT is clearly an int, and your column Max_off is clearly meant to be a decimal; as it is a percentage.

We'll fix Pro_Pct first. Firstly check if any values are "bad" (which I don't doubt there will be because you're storing numerical data as a nvarchar):

SELECT YourIdColumn
       Pro_PCT
FROM dbo.YourTable
WHERE TRY_CONVERT(int,Pro_PCT) IS NULL
  AND Pro_PCT IS NOT NULL;

That will give you a dataset back of all the bad data. You'll need to fix all of those values.

After that, you can ALTER the table:

ALTER TABLE dbo.YourTable ALTER COLUMN ProPCT int NULL; --Change to NOT NULL as appropriate

Now the percentage. First we need to remove all the percent ('%') characters and turn the value into a decimal. Again, let's get the bad data:

SELECT YourIDColumn,
       [Max_Off]
FROM dbo.YourTable
WHERE TRY_CONVERT(decimal(10,4),REPLACE(Max_Off,N'%',N''))
  AND Max_Off IS NOT NULL;

Again, fix all your values where it couldn't be converted. Then you can UPDATE the value and then ALTER the table:

UPDATE dbo.YourTable
SET Max_Off = TRY_CONVERT(decimal(6,4),REPLACE(Max_Off,N'%',N'')) / 100.00
GO
ALTER TABLE dbo.YourTable ALTER COLUMN Max_Off decimal(6,4) NOT NUll; --Again, change to NULL if needed

Now your data is fixed, you should have an easier time implementing the logic for IsExcess.