T-SQL BULK INSERT type mismatch - sql-server

I am trying to do a simple BULK INSERT from a large CSV file to a table. The table and the file have matching columns. This is my code:
BULK INSERT myTable
FROM 'G:\Tests\mySource.csv'
WITH (
FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
-- ROWTERMINATOR = '0x0a',
BATCHSIZE = 1000,
MAXERRORS = 2
)
GO
As you can see I have tried with row terminators \n and 0x0a (and a bunch more)
I keep getting a type mismatch error:
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 2, column 18 (createdAt).
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 3, column 18 (createdAt).
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 4, column 18 (createdAt).
Msg 4865, Level 16, State 1, Line 1
Cannot bulk load because the maximum number of errors (2) was exceeded.
Msg 7399, Level 16, State 1, Line 1
The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.
Msg 7330, Level 16, State 2, Line 1
Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".
Column createdAt is of type datetime:
CREATE TABLE [dbo].[myTable]
(
...
[createdAt] [datetime] NULL,
...
)
These are the values of the createdAt column as taken from the first three rows:
2020-08-22 13:51:57
2020-08-22 14:13:13
2020-08-22 14:16:23
I also tried with a different number format as suggested. I also tried changing the column type to DATETIME2(n):
2020-08-22T13:51:57
2020-08-22T14:13:13
2020-08-22T14:16:23
I have no idea what else to review.
I would appreciate any help.
Thanks!

There are many formats of string literals to be converted to dates & times supported by SQL Server - see the MSDN Books Online on CAST and CONVERT. Most of those formats are dependent on what settings you have - therefore, these settings might work some times - and sometimes not. And the DATETIME datatype in particular is notoriously picky about what formats of string literals work - and which others (most) don't.... DATETIME2(n) is much more forgiving and less picky to deal with!
The way to solve this is to use the (slightly adapted) ISO-8601 date format that is supported by SQL Server - this format works always - regardless of your SQL Server language and dateformat settings.
The ISO-8601 format is supported by SQL Server comes in two flavors:
YYYYMMDD for just dates (no time portion); note here: no dashes!, that's very important! YYYY-MM-DD is NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:MM:SS for dates and times - note here: this format has dashes (but they can be omitted), and a fixed T as delimiter between the date and time portion of your DATETIME.
This is valid for SQL Server 2000 and newer.
If you use SQL Server 2008 or newer and the DATE datatype (only DATE - not DATETIME!), then you can indeed also use the YYYY-MM-DD format and that will work, too, with any settings in your SQL Server.
Don't ask me why this whole topic is so tricky and somewhat confusing - that's just the way it is. But with the YYYYMMDD format, you should be fine for any version of SQL Server and for any language and dateformat setting in your SQL Server.
The recommendation for SQL Server 2008 and newer is to use DATE if you only need the date portion, and DATETIME2(n) when you need both date and time. You should try to start phasing out the DATETIME datatype if ever possible
In your case, I'd try one of two things:
if you can - use DATETIME2(n) instead of DATETIME as your column's datatype - that alone might solve all your problems
if you can't use DATETIME2(n) - try to use 2020-08-22T13:51:57 instead of
2020-08-22 13:51:57 for specifying your date&time in the CSV import file.

Related

SQL Server changing date format to accept d/m/y

An application is passing the below query to the SQL server and I'm receiving an exception from SQL server as The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
update Images set Created_DATE='23/09/2020 11:00:09'
where ID = 10
Additionally, I cant see the below error in Profiler.
What I've tried is,
Changes the Date format of SQL server as DMY
Change the language to en-GB
I can't change the code so how to make this work by changing SQL server configuration?
Try this:
update Images
set Created_DATE=CONVERT(DATETIME, N'23/09/2020 11:00:09', 103)
where ID = 10
You need to convert the string to date setting a culture. Otherwise, the engine is not able to understand the format as there are various formats.
I believe, your date type is DATETIME, and that's why you are getting this error:
SELECT CAST('23/09/2020 11:00:09' AS DATETIME);
result as:
Msg 242, Level 16, State 3, Line 4 The conversion of a varchar data
type to a datetime data type resulted in an out-of-range value.
for DATETIME2 it is:
Msg 241, Level 16, State 1, Line 4 Conversion failed when converting
date and/or time from character string.

BULK INSERT issues with SQL Server 2012 and higher releases

We work with a 3rd party and they provide us files that are basically a dump from their DB. Our company supports SQL Server 2012 as well as SQL Server 2014 and up. I need to BULK INSERT these files and have ONE set of files work for any client.
They provide us the files, from a UNIX system, as utf-8 encoded. I am aware that SQL Server 2012 doesn't support utf-8. From reading on here, I have gone the route of converting those files to utf-16 (using Textpad8). In total there are about 22 files.
I use the following syntax:
BULK INSERT database.dbo.tablename
FROM '\\server\filename.txt'
WITH (FIRSTROW =2, ROWTERMINATOR ='0x0a')
That of course works for all the files on SQL Server 2014 box.
ONE file of the 22 does NOT work for SQL Server 2012 and I cannot figure out what is wrong. That particular file goes into a table defined this way:
CREATE TABLE [dbo].[Map]
(
termid int NOT NULL,
mapguid char(22) NOT NULL,
mapsequence int NOT NULL,
conceptguid char(22) NOT NULL,
mapdefnguid char(22) NOT NULL,
mapquality int NULL,
CONSTRAINT [PK_Map]
PRIMARY KEY CLUSTERED ([termid] ASC, [mapguid] ASC, [mapsequence] ASC)
) ON [PRIMARY];
This is what the sample data looks like
termid mapguid mapsequence conceptguid mapdefnguid mapquality
260724 Nm9T2QFFs67xk2/zCgEDHw 0 AExH2wEce5u4wbhnqf4ZgQ TDMQWQE6UQdXAoATCgECyQ
172288 AW8L6AEj+br0hsZ3CgEBig 0 BgCTWgDjf6OlTk1oCwsLDQ AUKoDQEjn6KrxIAJCgEBmw
377707 PtArUQE7q1ajeoiRCgEDAQ 0 ACSYtQDsdrQtN1h2qf79/w TDMQWQE6UsYdrYAbCgECeg
tab is column separator, and LF is the rowterminator character
This is the error I get:
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 2, column 1 (termid).
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 3, column 1 (termid).
I've searched that error on google (and here) and have seen where you may get that error if something is actually specified as literally 'NULL' instead of being blank.
I've even gone so far as to create my own file and I still get the same errors. In my own file, I actually populate the last row, thinking maybe that was causing issues, but the error seems to indicate it doesn't like something with the very first column.
Can anyone help me with some suggestions please?
I don't know if this is REALLY an answer, but somehow, the file imports fine with utf-8 encoding, which doesn't make a lot of sense to me since SQL 2012 isn't supposed to support that. I looked at the data in the table and it appears to be fine, so I don't really have an explanation there.
I then converted the file to utf-16 and re-ran the process and started getting the above errors again, so...shrug

SQL Server - Select YEAR error

Currently using SQL Server 2008. In an effort to debug some bad date data being processed, the following code was written with an example of the bad data.
SELECT ISDATE('10-22-002')
SELECT YEAR('10-22-002')
Running the statements on database A, the results are: '1' and '2002'.
Running the statements on database B, the results are: '1' and an error.
The date format is MDY on all sessions before running the statements.
Msg 241, Level 16, State 1
Conversion failed when converting datetime from character string.
Everything I'm able to find says the date format is set at either server or session level. Is there a setting at the DB level for this?
You need to cast '10-22-002' as a datetime.
SELECT YEAR(cast('10-22-002' as datetime))

Date Conversion Issue MS Access to SQL Server

I'm creating a table B from an exisitng table A. In the table A I have a column ValDate which is varchar and contains Date. When I try to create the table B I have a function used in the query as given below and I get a conversion error. Table A contains null values as well.
MS Access:
((DateDiff("d",Date(),format(Replace(Replace([Table A].ValDate,".","/"),"00/00/0000","00:00:00"),"dd/mm/yyyy")))>0)).
Tables were in MS Access and are being migrated to SQL Server 2012.
SQL Server:
((DATEDIFF(day,FORMAT( GETDATE(), 'dd-MM-yyyy', 'en-US' ),FORMAT( ValDate, 'dd-MM-yyyy', 'en-US' ))>0))
or
((DateDiff(day,GETDATE(),Format(Replace(Replace([TableA].[ValidFrom],'.','/'),'00/00/0000','00:00:00'),'dd/mm/yyyy')))
I tried converting the date using several approachs like Convert , Format and Cast but I end up getting error as below.
Msg 8116, Level 16, State 1, Line 1
Argument data type date is invalid for argument 1 of isdate function.
I would really appreciate someone telling me what I'm missing here.
since you have date data in a string field is very likely you have some value that is not valid against your expected date format.
copy the data in a sql server table and then perform check and validation of the content of the string field.
have a look to the function try_convert that can be helpful when checking the content of the string field containing the date values.
when bad data is ruled out you can apply again your formula with (hopefully) a different result.
a better solution would be to create a separate field with appropriate datatype to store date values converted from the string field and apply your logic to that field.

Bulk load data conversion error while importing DATETIME data

I found a few posts on this topic on StackOverflow, but none seem to solve my problem.
I am trying to set up bulk imports for SQL Server 2008 Express, and it is failing to import datetime values. The issue seems so basic that I must be missing something very simple, and I'm hoping someone else can catch the problem.
The Problem
I am importing into this table:
CREATE TABLE [dbo].[BulkTest](
[ReportDate] [datetime] NOT NULL
)
This is my format file (BulkTest.fmt):
10.0
1
1 SQLDATETIME 0 0 "\r\n" 1 ReportDate ""
This is the data being imported (BulkTest.tab):
ReportDate
2010-12-31
2011-01-31
This is the import statement:
BULK INSERT dbo.BulkTest
FROM 'Q:\...\BulkTest.tab'
WITH (
CHECK_CONSTRAINTS,
TABLOCK,
FORMATFILE='Q:\...\BulkTest.fmt',
FIRSTROW=1,
DATAFILETYPE='char'
);
These are the errors:
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 1, column 1 (ReportDate).
Msg 4864, Level 16, State 1, Line 1
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 2, column 1 (ReportDate).
Msg 4832, Level 16, State 1, Line 1
I Have Tried
Changing the date format, including 12/31/2010, 31/12/2010, 20101231, 2010-12-31 00:00:00, and various other formats.
Adding/removing/changing bulk insert statement options DATAFILETYPE, TABLOCK, CHECK_CONSTRAINTS.
Changing the delimiter and the field size in the format file (though per MSDN the field size should not matter).
Running SET DATEFORMAT ymd.
Checking the imported file with hex editor to make sure that it really does contain 8-bit chars and not unicode; it contains exactly what is shown in ASCII format.
Any ideas?
This is the format that works in my code:
08/17/2000 16:32:32
The producer happens to be .NET, ToString(DateTimeFormatInfo.InvariantInfo).
Why do you need a format file for this? What happens when you don't use it?
BULK INSERT dbo.BulkTest
FROM 'Q:\...\BulkTest.tab'
WITH (
CHECK_CONSTRAINTS,
TABLOCK,
FIRSTROW=1,
DATAFILETYPE='char',
ROWTERMINATOR='\r\n'
);
Sorry I'm late to the party but I hope this can help some other poor soul.
Anyway I discovered the same error when using the format file.
Instead of type SQLDATE I used SQLCHAR and the length.
2015-01-01 = length 10
11.0
1
1 SQLCHAR 0 10 "\r\n" 1 my_date ""

Resources