"Error converting data type varchar to numeric." - What column? - sql-server

I have a huge INSERT-statement with 200 columns and suddendly I get the dreaded Error converting data type varchar to numeric. Is there somewhere I can see the actual column that contains the "varchar" value? I know I can remove one of the columns at a time until the error disappears, but it's very tedious.

Unfortunately, this error is a serious pain and there's no easy way to troubleshoot it. When I've encountered it in the past, I've always just had to comment out groups of columns until I find the culprit.
Another approach might be to use the ISNUMERIC() function in in T-SQL to try and find the culprit. Assuming every column in your destination table is numeric (adjust accordingly if it's not), you could try this:
SELECT *
FROM SourceTable
WHERE ISNUMERIC(Column1) = 0
OR ISNUMERIC(Column2) = 0
OR ISNUMERIC(Column3) = 0
OR ISNUMERIC(Column4) = 0
...
This will expose the row that contains your non-numeric value, and should make it pretty clear which column it's in. I know it's tedious, but at least it helps you hunt down the actual value, in addition to the column that's causing trouble.

You don't specify SQL Server Version or number of rows.
For SQL2005+ adding the OUTPUT clause to the INSERT might help identify the rogue row in that it will output the inserted rows until it encounters an error so the next row is the one with the problem
DECLARE #Source TABLE
(
Col1 VARCHAR(10),
Col2 VARCHAR(10)
)
INSERT INTO #Source
SELECT '1','1' UNION ALL
SELECT '2','2' UNION ALL
SELECT '3','3' UNION ALL
SELECT '4A','4' UNION ALL
SELECT '5','5'
DECLARE #Destination TABLE
(
Col1 INT,
Col2 VARCHAR(10)
)
INSERT INTO #Destination
OUTPUT inserted.*
SELECT *
FROM #Source
Returns
(5 row(s) affected)
Col1 Col2
----------- ----------
1 1
2 2
3 3
Msg 245, Level 16, State 1, Line 23
Conversion failed when converting the varchar value '4A' to data type int.

Well, this is just a hunch but what about inserting the data to a temporary table and the using the GUI to migrate the data to the other table? If it still generates an error, you should at least be able to get more feedback on that non-numerical column...
If it doesn't work, consider trying this.
Cheers!

Related

Inserting a distinct entry into db.table results into implicit conversion error in SQL Server

I have a requirement where I need to insert new entries found in a record into its Master Table and Map the ID of the identifier to the main table
For Instance consider the below example,
-- Insert into Category Master if not exists
INSERT INTO tblCategoryMaster (Category,
CreatedBy,
CreatedDate,
UpdatedBy,
UpdatedDate)
SELECT DISTINCT
(category),
SERVERPROPERTY('MACHINENAME'),
GETDATE(),
SERVERPROPERTY('MACHINENAME'),
GETDATE()
FROM tblTempDataStaging stg
WHERE category IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM tblCategoryMaster ctg WHERE ctg.Category = stg.category);
After executing the select query we get list of distinct entries and every time a new entry is entered in the staging table, the entries are populated in the Master Table accordingly.
Server is not allowing me to insert, its giving me an error saying
Msg 257, Level 16, State 3, Line 39
Implicit conversion from data type sql_variant to nvarchar(max) is not allowed. Use the CONVERT function to run this query.
The data type of the staging table is NVARCHAR(MAX) for the relevant fields except datetime for the date fields
Tried using CONVERT method but I'm unsure on how do we use it with DISTINCT in the picture
Can you suggest how do I resolve this issue?
The error is telling you the problem: SERVERPROPERTY('MACHINENAME') returns the datatype sql_variant:
SELECT system_type_name
FROM sys.dm_exec_describe_first_result_set(N'SELECT SERVERPROPERTY(''MACHINENAME'') AS MachineName',NULL,NULL);
The underlying data type is a nvarchar (thought it certainly won't be 2GB of storage for the name of a machine!) as can be seen here:
SELECT SQL_VARIANT_PROPERTY(SERVERPROPERTY('MACHINENAME'),'Basetype')
You need to explicitly convert the value. For example:
CONVERT(nvarchar(256),SERVERPROPERTY('MACHINENAME'))
I do suggest you change the data type of your column CreatedBy, and I assume UpdatedBy, from nvarchar(MAX) to something like an nvarchar(256); you don't need 2GB of characters (about 1 Billion) to store that information.

SQL Server changes the value in the float column when converting to varchar

I have a column in my table that is of float type. The table was automatically generated when I imported the spreadsheet (Excel) data to my database. Thus there is a column I wish to change from float to varchar, but when I try to do this, I get an error:
'tblInvoices' table
Unable to create index 'IX_tblInvoices'.
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.tblInvoices' and the index name 'IX_tblInvoices'.
The duplicate key value is (1.00001e+006). The statement has been terminated.
It is a unique column, and set that way (not set as the primary key for reasons). I have already run queries to search for and delete duplicate fields but there are none. The query I ran as follows:
WITH CTE AS
(
SELECT
Invoice,
RN = ROW_NUMBER()OVER(PARTITION BY Invoice ORDER BY Invoice)
FROM
dbo.tblInvoices
)
DELETE FROM CTE
WHERE RN > 1
So the value within the Invoice column is 1000010 and when I run the following query a single row is found.
SELECT *
FROM [TradeReceivables_APR_IFRS9].[dbo].[tblInvoices]
WHERE Invoice = 1.00001e+006
Note that I have searched for the value in the error, 1.00001e+006, and not 1000010.
So my question is why does the DBMS do this? Why does it change the value like that? When I remove the column, it does it with another column and so on and so on (about 40 000 rows in total). How can I change the column from float to varchar without changing the data and getting errors?
Any help will be greatly appreciated!
It seems that the field is an integer so you can Cast it to BIGINT before cast to VARCHAR
Declare #Invoice as float = 1.00001e+006
print cast(#Invoice as varchar) -->> Result : 1.00001e+006
print cast(cast(#Invoice as bigint) as varchar) -->> Result : 1000010

not able to identify difference between same value

I have data inside a table's column. I SELECT DISTINCT of that column, i also put LTRIM(RTRIM(col_name)) as well while writing SELECT. But still I am getting duplicate column record.
How can we identify why it is happening and how we can avoid it?
I tried RTRIM, LTRIM, UPPER function. Still no help.
Query:
select distinct LTRIM(RTRIM(serverstatus))
from SQLInventory
Output:
Development
Staging
Test
Pre-Production
UNKNOWN
NULL
Need to be decommissioned
Production
Pre-Produc​tion
Decommissioned
Non-Production
Unsupported Edition
Looks like there's a unicode character in there, somewhere. I copied and pasted the values out initially as a varchar, and did the following:
SELECT DISTINCT serverstatus
FROM (VALUES('Development'),
('Staging'),
('Test'),
('Pre-Production'),
('UNKNOWN'),
('NULL'),
('Need to be decommissioned'),
('Production'),
(''),
('Pre-Produc​tion'),
('Decommissioned'),
('Non-Production'),
('Unsupported Edition'))V(serverstatus);
This, interestingly, returned the values below:
Development
Staging
Test
Pre-Production
UNKNOWN
NULL
Need to be decommissioned
Production
Pre-Produc?tion
Decommissioned
Non-Production
Unsupported Edition
Note that one of the values is Pre-Produc?tion, meaning that there is a unicode character between the c and t.
So, let's find out what it is:
SELECT 'Pre-Produc​tion', N'Pre-Produc​tion',
UNICODE(SUBSTRING(N'Pre-Produc​tion',11,1));
The UNICODE function returns back 8203, which is a zero-width space. I assume you want to remove these, so you can update your data by doing:
UPDATE SQLInventory
SET serverstatus = REPLACE(serverstatus, NCHAR(8203), N'');
Now your first query should work as you expect.
(I also suggest you might therefore want a lookup table for your status' with a foreign key, so that this can't happen again).
DB<>fiddle
I deal with this type of thing all the time. For stuff like this NGrams8K and PatReplace8k and PATINDEX are your best friends.
Putting what you posted in a table variable we can analyze the problem:
DECLARE #table TABLE (txtID INT IDENTITY, txt NVARCHAR(100));
INSERT #table (txt)
VALUES ('Development'),('Staging'),('Test'),('Pre-Production'),('UNKNOWN'),(NULL),
('Need to be decommissioned'),('Production'),(''),('Pre-Produc​tion'),('Decommissioned'),
('Non-Production'),('Unsupported Edition');
This query will identify items with characters other than A-Z, spaces and hyphens:
SELECT t.txtID, t.txt
FROM #table AS t
WHERE PATINDEX('%[^a-zA-Z -]%',t.txt) > 0;
This returns:
txtID txt
----------- -------------------------------------------
10 Pre-Produc​tion
To identify the bad character we can use NGrams8k like this:
SELECT t.txtID, t.txt, ng.position, ng.token -- ,UNICODE(ng.token)
FROM #table AS t
CROSS APPLY dbo.NGrams8K(t.txt,1) AS ng
WHERE PATINDEX('%[^a-zA-Z -]%',ng.token)>0;
Which returns:
txtID txt position token
------ ----------------- -------------------- ---------
10 Pre-Produc​tion 11 ?
PatReplace8K makes cleaning up stuff like this quite easily and quickly. First note this query:
SELECT OldString = t.txt, p.NewString
FROM #table AS t
CROSS APPLY dbo.patReplace8K(t.txt,'%[^a-zA-Z -]%','') AS p
WHERE PATINDEX('%[^a-zA-Z -]%',t.txt) > 0;
Which returns this on my system:
OldString NewString
------------------ ----------------
Pre-Produc?tion Pre-Production
To fix the problem you can use patreplace8K like this:
UPDATE t
SET txt = p.newString
FROM #table AS t
CROSS APPLY dbo.patReplace8K(t.txt,'%[^a-zA-Z -]%','') AS p
WHERE PATINDEX('%[^a-zA-Z -]%',t.txt) > 0;

SQL Server: Search input on multiple columns

i was trying to search a single term on multiple columns. i got error because one of column was date time. how could i make a generic search with in-line sql. this way i tried.
create table tbl_test1
(id int identity(1,1),
column1 nvarchar(50),
coulmn2 nvarchar(50),
coulmn3 nvarchar(50),
coulmn4 datetime)-- Create a table
insert into tbl_Test1 (column1,coulmn2,coulmn3,coulmn4) values
('Griff','Serjey','Maciej',GETDATE()),
('King','Fisher','Ajay',GETDATE()),
('Paul','Griff','Serjey',GETDATE()),
('King','Fisher','Griff',GETDATE())
select * from tbl_Test1 where 'Griff' IN (column1,coulmn2,coulmn3,coulmn4)
i got this error.
Conversion failed when converting date and/or time from character
string.
to fix your requirement, you can first convert column4, yourdatetime column to nvarchar(max) first
select * from tbl_Test1 where 'Griff' IN
(column1,coulmn2,coulmn3,convert(nvarchar(max),coulmn4))
however this is not recommended to do so because of performance issues =x
From 2012,,you can use..TRY_Convert
select * from #tbl_Test1
where 'Griff'
IN (column1,coulmn2,coulmn3,try_convert(varchar(10),coulmn4))
You may need to do similar cast and convert on other columns when you search with date columns
You already know that your column4 is of type datetime then why do we search your string with that column. Just ignore that column
Try like this,
SELECT *
FROM tbl_test1
WHERE 'Griff' IN (
column1
,coulmn2
,coulmn3
)

What can cause "The conversion of a char data type to a datetime data type resulted in an out-of-range"?

I am running into an error I am having trouble figuring out.
I have 2 tables and I'm trying to copy data from one to the other (simplified view):
MyTable
-------
ID varchar(11) do not allow nulls
Field01 numeric(6,0) allow nulls
MyTable_Temp
------------
ID varchar(11) do not allow nulls
Field01 numeric(6,0) allow nulls
My query looks like this:
DELETE FROM dbo.MyTable
INSERT INTO dbo.MyTable([ID],[Field01])
SELECT ID, Field01 FROM [dbo].MyTable_Temp WITH (NOLOCK)
However when I run my query it throws this error:
Msg 242, Level 16, State 3, Procedure TRG_MyTable, Line 6
The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value.
If I comment out the Field01 part of the query it runs fine. How can a numeric field throw a datetime error?
It looks to me like you've got some kind of trigger on the destination table that's firing (TRG_MyTable is a giveaway) It's probably doing something like inserting a timestamped record into an audit table somewhere and is getting confused.

Resources