What is the easiest way to track down an Insert Into error? - sql

I'm working with a rather large Insert Into . . Select . . From . .
I have over 500+ lines of SQL in this script and I'm getting this error:
INSERT INTO MtgeMaster ( [Col1]
,[Col2]
,[Col3]
, etc., etc. )
SELECT [Col1]
,[Col2]
,[Col3]
, etc., etc.
FROM MtgeMktg
When I run the code above I get this error:
Msg 8114, Level 16, State 5, Line 164
Error converting data type varchar to numeric.
It looks like the error comes from line 164, but line 164 is literally my [Col1] field, and this is VARCHAR. So, I'm going from VARCHAR to VARCHAR. There is no VARCHAR to NUMERIC.
Also, if I add a couple of blank lines and re-run the process, I get this:
Msg 8114, Level 16, State 5, Line 166
Error converting data type varchar to numeric.
All it's really doing is going to the line with the INSERT INTO clause.
The error must be coming from another line, but it's hard to tell what's throwing the error when I have 500+ lines of SQL to go through.

SQL Server does not makes this easy. I have found that a brute force approach is necessary. I like to start by loading the data into a staging table where all the columns are strings. This makes it easier to manipulate.
You can use one of two methods to find the error. The first is to use try_convert() on each column to determine where the error is.
The second is to do a binary search to find the offending row. Load the first half of the data to see if the error is there. Then divide that half in half. And so on.

It looks like the error before and after adding few blank lines is same. It is probably a datatype conversion issue. You could try using cast() function and convert the data type of the [Col1] in select field of MtgeMktg table to match with the datatype of [Col1] of the MtgeMaster table.

So, here's my attempt to answer this question, based on what is given.
I would review the table structure of MtgeMaster, and see what columns are supposed to be numeric. Let's just say, for this example, Col3 of MtgeMaster is numeric. You may have multiple numeric columns.
I would then query MtgeMktg and check whether the column you're trying to save from MtgeMktg to MtgeMaster is numeric or not. You may have to do this for each column that is numeric in MtgeMaster. If I were doing it (which I did in SQLFiddle), it would be something to the nature of the following:
select * from MtgeMktg where ISNUMERIC(Col3) = 0
Anything that returns from this query will tell you what rows have a non numeric column.
Simple fiddle listed here:
Obviously, you would have 1 of 2 decisions to make at this point. Fix the data, or filter out the rows that have the non-numeric data in it. I presume you'd need the rows though.

Related

Msg 245, Level 16, State 1, Line 4 Conversion failed when converting the nvarchar value '239.6' to data type int

I have this query:
SELECT SerialNumber
FROM [ETEL-PRDSQL].[ERP10DBLIVE].[ERP].[SerialNo]
WHERE CustNum IN (2);
It's causing this error:
Msg 245, Level 16, State 1, Line 4
Conversion failed when converting the nvarchar value '239.6' to data type int.
The query works if I compare CustNum with a different value, but it fails when I try CustNum IN (2).
How can I fix this?
You have a varchar column named CustNum. The varchar values in this column may contain only digits, but that doesn't make them numbers! Then you compare this text column with the integer value 2. Again, the integer value 2 is not the same as the text value '2'. It's also not the same as the floating point value 2.0. These are all different, they have different types, and SQL Server must resolve any such differences before it can compare values.
Based on type precedence rules SQL Server determines it needs to convert the text in the column to the integer, instead of vice versa. Once this determination is made for the query, if you have any data in the text column that is not integer-compatible, the query is going to fail.
It's important to understand this conversion happens separately from the conditional check in the WHERE clause, and is a prerequisite for that check. It's not enough to expect the WHERE condition to evaluate to FALSE for rows that do not convert. This is true even if you don't need the row, because SQL Server can't know you don't need that row until after it attempts the conversion!
In this case, we have the value 293.6. This value may be numeric, but it is not an integer. Nor is it convertible to integer. Therefore the query fails.
In addition to (eventually!) failing the query, this is absolutely awful for performance. SQL Server has to do this conversion for every row in the table... even rows you don't need. This is because SQL Server doesn't know which rows will match the WHERE clause until after it checks the conditional expression, and it needs to do this conversion in order to make that check. Worse still, the new converted value no longer matches your indexes, so any indexes you might have become worthless for this query. That cuts to the core of database performance.
If you don't like it, define your data types better, or trying comparing the string with another string:
SELECT SerialNumber
FROM [ETEL-PRDSQL].[ERP10DBLIVE].[ERP].[SerialNo]
WHERE CustNum IN ('2');
The query might also run if you did this:
SELECT SerialNumber
FROM [ETEL-PRDSQL].[ERP10DBLIVE].[ERP].[SerialNo]
WHERE CustNum IN (2.0);
Now the type precedence rules will convert your text to a floating point type, and it's possible that will succeed if the rest of the values in the table are compatible. It's also possible this is closer to what you intend... but again, the performance here will be much worse.

Error converting data type varchar to bigint: INSERT INTO SELECT

I keep getting this error when trying to execute a stored procedure and am not sure why:
Msg 8114:
Error converting data type varchar to bigint.
Please see my SQL query below:
INSERT INTO StagingArea.dbo.DimStudentsTEST
(StudentCode, Module, Year, UniqueStudentID)
SELECT DISTINCT
RTRIM(S.STUDENT_Student_ID) +
RTRIM(SUBSTRING(AY.ACADEMYR_Academic_Year_Code, 3, 2) +
SUBSTRING(AY.ACADEMYR_Academic_Year_Code, 8, 2)) AS 'UniqueStudentID',
...
FROM
...
INNER JOIN
...
I believe the error is emerging because of the UniqueStudentID I have tried using CAST & CONVERT around the SELECT line but still no luck. Perhaps I am using in the wrong way. I have a feeling it is maybe because the column of the table I am pulling the data from ("AY.ACADEMYR..") is not of datatype 'bigint' so the error message keeps occuring. The datatype of the 'UniqueStudentID' column is of datatype 'bigint'
Can anyone see where the problem lies or if I am meant to use the CAST/CONVERT function then how best to use in this scenario.
Many thanks,
Assuming the columns are in the proper order during the INSERT.
I suspect you there may be some unexpected data/strings in the underlying components.
To identify the bogus records, try the following using try_convert(). As you may know, try_convert() will return a NULL if the conversion fails.
Example
Select *
From ...
Where try_convert(bigint,RTRIM(S.STUDENT_Student_ID)+RTRIM(SUBSTRING(AY.ACADEMYR_Academic_Year_Code,3,2)+SUBSTRING(AY.ACADEMYR_Academic_Year_Code,8,2))) is null

UNION ALL Statement Failing

I am trying to UNION ALL around 20 or so tables to consolidate into a single view. I keep getting an error that states:
'The numeric value XXXXX is not recognized'.
This error is contained in 1 column in each of the tables, but the data type for that column is VARCHAR(256) in each of the tables. No matter what I cast the column to I still get the same error.
The UNION ALL works perfectly if I comment that column out.
I've tried casting all columns to the same datatype, no luck.
I've tried commenting out the column in question, which works, but I need that column.
I've tried only UNION-ing a few of the tables, which sometimes works and sometimes doesn't, depending on the document type.
SELECT
CAST(QUICKBOOKS_MEXICO.BILL_LINE.DESCRIPTION AS VARCHAR(256)) AS DESCRIPTION
FROM QUICKBOOKS_MEXICO.BILL_LINE
UNION ALL
SELECT
CAST(QUICKBOOKS_EUROPE_BV.PURCHASE_LINE.DESCRIPTION AS VARCHAR(256)) AS DESCRIPTION
FROM QUICKBOOKS_EUROPE_BV.PURCHASE_LINE
The columns should seamlessly UNION.
Here is the error message:
Numeric value 'Exchange Gain Or Loss' is not recognized
It's worth mentioning that if I remove all the other fields BESIDES the column that is throwing the error from the query, it performs just fine. Truly baffling!
It seems to me that the error message that you get is not related to this column, but with another column where you might be casting the data as NUMERIC, but instead getting this value 'Exchange Gain Or Loss'.
One way to ignore this conversion error, is to use TRY_CAST instead of CAST, so when a value can not be converted to the intended data type, it will simply return NULL

Not Able to Insert Data into Database String or binary data would be truncated

INSERT INTO [CVSUAT].[dbo].[UserLevel ](
[Client_ID]
,[User_Level_Name]
,[User_Level_Description]
,[Created_by]
,[Created_Date]
,[Modified_by]
,[Modified_Date]
,[Delete_Flag]
,[Deactivate_Flag]) VALUES ('sndbsndbsdnbsndbsnbdnsbdn23','Client','','Client','2013-03-12 21:31:38.437','Client','2013-03-12 21:31:38.437','0','0')
Msg 8152, Level 16, State 4, Line 1
String or binary data would be truncated.
The statement has been terminated.
NOTE: My Table has a space [UserLevel ] as it was made that way from before
This is caused by attempting to put too much data into a column.
The trouble is, none of the values specified in your example are too large for the columns indicated in your schema picture. I'd therefore assume that the values you've given us either aren't the true values, or you've got a trigger on that table, which is actually what is causing the error.
As an aside, shouldn't your Delete_Flag and Deactivate_Flag columns be of datatype bit, rather than char(1)?
Edit:
Oh, and one more thing - as Client_ID is an nvarchar, you probably want to store unicode data in there. To indicate this in your script, you should use the "N" prefix on your strings, like so:
INSERT INTO [CVSUAT].[dbo].[UserLevel ](
[Client_ID]
,[User_Level_Name]
,[User_Level_Description]
,[Created_by]
,[Created_Date]
,[Modified_by]
,[Modified_Date]
,[Delete_Flag]
,[Deactivate_Flag]) VALUES (N'sndbsndbsdnbsndbsnbdnsbdn23','Client','','Client','2013-03-12 21:31:38.437','Client','2013-03-12 21:31:38.437','0','0')

Why can't SQL Server tell me which column is causing the error

I'm running a pretty standard
INSERT INTO [table] (col1, col2, ...coln)
select * from #temp
and I'm getting the following error:
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'NULL' to data type int.
I understand the error, but want to know why the column that is causing issue isn't identified by the error message. Is there an easy way to find which column contains the naughty null or is this just a ploy to make me look like I'm being productive at work while I really just spent 30 minutes looking at a huge result set without getting anywhere?
Edit: Thanks for the help guys, but no one really answered the question. Do all RDBMS's spew out similar error messages are or some more helpful? Its 2012...trial and error over possibly thousands of columns should be dead!
I would look at how you populate the temp table. You appear to be getting a value of 'null' not NULL. If this data is coming from a Excel file, this is a common problem. I usually clease the data first by updating this way:
Update #temp
set field1 = NULL
where field1 = 'NULL'
If you want to do all in the same update command, then
Update #temp
set field1 = NULLIF(field1, 'NULL')
, field2 = NULLIF(field2, 'NULL')
, field3 = NULLIF(field3, 'NULL')
It shouldn't take you 30 minutes to figure out where the null is. You only have so many columns. Just start selecting from #temp WHERE col1 IS NULL, then WHERE col2 is.
If #temp has a VARCHAR column you're trying to put into in INT column then cast it. If there are NULLs you might want to handle them with an CAST(ISNULL(VarCharColumn, '0') AS INT) or something. If an INT column allows NULLS, then just the cast to INT should be enough (as long as all the values are NULL or a valid int).
If you write your INSERT with a little bit more care then you should be able to get the results you want.
You're going to need some trial and error as #Jeremy pointed out. But you can winnow down the choices.
The error message says that the problem is a NULL in a varchar column. You can restrict your searching to just the varchar columns in #temp: select * from #temp where col1 is null or col3 is null
Second, the problem is also happening when the database engine tries to convert a null varchar value to an integer not null. Compare the definitions of both tables to see where a varchar in #temp matches up with an integer not null in the other table.
This, however, is suspicious. Why are you trying to convert text to numbers? If that's what you really want to do, you will probably need an explicit cast from textual to numeric.
If you run these two statements before your query you will see null values on those columns in the results set:
SET ARITHABORT OFF
SET ANSI_WARNINGS OFF