bulk insert datetime data - sql

I try to bulk insert some datetime values in this format:
31/12/2005 00:00:00
using something like this:
create table Seed
(
StartDate datetime not null
)
BULK INSERT Seed
FROM 'd:\dump\Seed.txt'
WITH
(
firstrow=2,
FIELDTERMINATOR = '\t',
ROWTERMINATOR = '\n'
)
But I get this:
Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row
I know how to define a codepage but which? Is there a simple solution?
Thanks.
Christian

What is the default language for the user logged in to the SQL instance while running this T-SQL? The date format you specified 31/12/2005 00:00:00 looks to be British and perhaps your default language is US_English.
Try running this T-SQL to determine your current language:
SELECT ##language, ##langid
If it's US_English, then your date format should be mm/dd/yyyy hh:mm:ss
To keep your example alive, try changing your default language for the current user by doing the following:
--Get the current language setting for connected user
SELECT ##LANGUAGE,##LANGID
--Get information about all languages
EXEC sys.sp_helplanguage
--Get the name of the current user
DECLARE #sysuser NVARCHAR(30)
SET #sysuser = SYSTEM_USER
PRINT #sysuser
EXEC sp_defaultlanguage #sysuser, 'british' --satisfying your example date
After you have changed the default language, reconnect your query window and you should be now utilizing the new default language.
To get back to the previous language setting, just EXEC sp_defaultlanguage again with the language setting you previously had.
Hopefully that works!

SQL Server is not going to convert the DD/MM/YYYY date format correctly. You'll need to either reformat your input file as MM/DD/YYYY or insert into a char/varchar datatype and then manipulate the string into the correct format for another datetime column. For example:
create table TempSeed
(
StartDate varchar(50) not null
)
BULK INSERT TempSeed
FROM 'd:\dump\Seed.txt'
WITH
(
firstrow=2,
FIELDTERMINATOR = '\t',
ROWTERMINATOR = '\n'
)
create table Seed
(
StartDate datetime not null
)
insert into Seed
(StartDate)
select CAST(substring(ts.StartDate,4,3) + stuff(ts.StartDate,4,3,'') as datetime)
from TempSeed ts

Related

Change Date format during SQL

I am moving data to a new database and need to so some formatting during the move to try and save me time.
The current DB saves the date as YYYYMMDD and the new DB wants it in mm/dd/yyyy. Can I do this during the move or will I have to format after?
Thank you all!
You cold use the format function . So I am not sure how you are getting the data to sql 2014 but once the data is there you could use this command.
This is an example selecting from a table that has a date and altering its format .
use AdventureWorks2012
go
select modifieddate as 'original format', FORMAT ( modifieddate, 'd', 'en-US' ) AS 'New format mm/dd/yy'
from [Sales].[SalesOrderDetail]
Query Result
If your data is not format and its just a string you could use the format command to add the separators .
This code create a table with a date as an INT, the selects the data and formats it as a data time into another table .
CREATE TABLE Test_TimeString (Timeint int)
GO
INSERT INTO Test_TimeString VALUES(04242016)
GO
CREATE TABLE Test_Time (Timedate DATETIME)
GO
INSERT INTO Test_Time
SELECT FORMAT(Timeint,'##/##/####')
FROM Test_TimeString
SELECT * FROM Test_Time

Converting Oracle TIMESTAMP(6) TO SQL SERVER 2008 DATETIME2(6)

I am bulk importing a csv file to SQL server 2008, the csv file has been generated from exporting the table data from Oracle SQL developer.
The data for one column in that csv file is in TIMESTAMP(6) for which I am having the DATETIME2(6) datatype for the required column in the SQL server 2008.
I am importing the CSV file using the below statement
USE H_CLAIMS
GO
BULK INSERT H_CLAIMS.dbo.APPLICATION_QUEUES
FROM 'D:\MyWork\HC DB Work\HCAIDDB_CSV_EXPORTS\APPLICATION_QUEUES_export.CSV'
WITH (FIELDTERMINATOR = ',', ROWTERMINATOR = '\n')
GO
while doing above I am getting the below 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 1, column 5 (CREATED_DATE).
Msg 4864, Level 16, State 1, Line 1
The sample data in the column mentioned in the error is like
21-NOV-14 08.57.51.565214000 AM
So I am looking for the answer, which can overcome this issue with any other attributes during the bulk insert statement or any convert function which can properly convert the datetime in the sample data to SQL SERVER 2008 datetime2 format.
SQL Server doesn't know how to convert the text value " 21-NOV-14 08.57.51.565214000 AM" to a DATETIME2 column. Try it in a query analyser window :
SELECT CAST('21-NOV-14 08.57.51.565214000 AM' AS DATETIME2(6))
Note that if you're using DATETIME2(6) it'll be loosing precision compared to what you're trying to import. Have a look at http://msdn.microsoft.com/en-GB/library/bb677335.aspx.
When I've had to do this coming from DB2 text files, I've done it two different ways.
Import the datetime field into a varchar then written a bit of SQL to manipulate the string into a format SQL Server can recognise, so something like. Bit slow and clunky, especially if you have a lot of data.
Use SSIS and create a transformation to do the string manipulation there. This has the advantage of still being able to bulk insert into the destination table, but does mean you need to be able to have access to integration services.
As I couldn't find any bulk Insert which will do the work for me, I have gone with a different approach. After many trails with cast and convert, I followed the below approach which is working as expected
I have created a function which can convert the oracle timestamp(6) to nvarchar of sql which can be directly inserted as datetime2(6) datatype in sql server 2008. Below is the function
Then I have used a stored procedure which can accept the file path as input parameter and a temp table to hold the nvarchar based datetime2 value. In the stored procedure I have used the dynamic bulk insert statement to insert into the required table. The procedure is after the function
CREATE FUNCTION DATETIMECONVERTER
(
#ORACLETIMESTAMP NVARCHAR(100)
)RETURNS nvarchar(100)
AS
BEGIN
DECLARE #convertedString nvarchar(100);
select #convertedString= replace(#ORACLETIMESTAMP,'.',':');
RETURN STUFF(#convertedString, CHARINDEX(':', #convertedString,18), 1, '.')
END
GO
CREATE PROCEDURE IMPORT_APPLICATION_ROLES #PATH varchar(1000)
AS
IF OBJECT_ID('H_CLAIMS.DBO.TEMP_APPLICATION_QUEUES', 'U') IS NOT NULL
DROP TABLE H_CLAIMS.DBO.TEMP_APPLICATION_ROLES
CREATE TABLE H_CLAIMS.DBO.TEMP_APPLICATION_ROLES
(
ROLE_ID INT NOT NULL,
ROLE_NAME NVARCHAR(255),
ROLE_DESC NVARCHAR(255),
CREATED_BY NVARCHAR(100),
CREATED_DATE NVARCHAR(100),
UPDATED_BY NVARCHAR(100),
UPDATED_DATE NVARCHAR(100)
)
DECLARE #bulkInsert NVARCHAR(4000) = 'BULK INSERT TEMP_APPLICATION_ROLES FROM ''' + #PATH + ''' WITH ( FIELDTERMINATOR ='','', ROWTERMINATOR =''\n'' )';
EXEC(#bulkInsert)
INSERT INTO APPLICATION_ROLES
(ROLE_ID,ROLE_NAME,ROLE_DESC,CREATED_BY,CREATED_DATE,UPDATED_BY,UPDATED_DATE)
SELECT ROLE_ID,ROLE_NAME,ROLE_DESC,CREATED_BY,dbo.DATETIMECONVERTER(CREATED_DATE)AS CREATED_DATE,
UPDATED_BY,dbo.DATETIMECONVERTER(UPDATED_DATE) AS UPDATED_DATE
FROM H_CLAIMS.dbo.TEMP_APPLICATION_ROLES
DROP TABLE H_CLAIMS.DBO.TEMP_APPLICATION_QUEUES
GO
to execute the statment I have used the below statement
EXEC H_CLAIMS.DBO.IMPORT_APPLICATION_QUEUES #PATH='D:\my_export.CSV';
Make sure to place the .csv files in the server machines drive while executing the stored procedure
I may be late to answer this but allow me to give you my workaround (if the precision doesn't really matter)
I import the timestamp from oracle table into SQL 2008 varchar then I update the varchar into a format that will fit for datetime2 then I alter the SQL table column to data type datetime2.
EG: in case you have time stamp like '01-JAN-15 12.00.00.000000000 AM +05:30'
update My_Table
set MyTimeStamp =
substring(MyTimeStamp, 1,10)+
REPLACE(substring(MyTimeStamp, 11, 8),'.',':')+
substring(MyTimeStamp, 19, 13)
where MyTimeStamp like '%.%.%.%';
alter table [My_Table] alter column MyTimeStamp DATETIME2;
Go;

Inserting date in sql server

When I try to execute this query
INSERT INTO StateRegion
( FullName ,
Abbreviation ,
RegionType ,
Admitted ,
Capital
)
VALUES ( 'Alabama' ,
'AL' ,
1 ,
'1819-Dec-14' ,
'Montgomery'
);
it gives me error sql date conversion error :
Conversion failed when converting date and/or time from character
string
Admitted is a Date type.
The issue is I can not change this format : 1819-Dec-14, is it possible to add convert method to the query above ?
Table definition :
CREATE TABLE StateRegion
(
ID bigint PRIMARY KEY IDENTITY(1,1),
FullName varchar(50) NOT NULL,
Abbreviation varchar(2) NOT NULL,
RegionType smallint NOT NULL,
Admitted date NULL,
Capital varchar(50) NULL
);
The month name part of that date format is interpreted according to the language of the login.
You can change the default language of the login to US English or British English if you must work with that format or issue a
Set language english
To set the format at run time before the problematic query then optionally switch it back afterwards.
If you have the choice using yyyy-mm-dd or yyyymmdd would be preferable formats for date literals though that both avoid this issue when casting to date.
Use a parameterized query. Parameterization will send the date to the server in binary, avoiding any string conversions which depend upon the client locale.
Example in C#:
SqlCommand sqc = new SqlCommand("INSERT INTO MyTable (DateColumn) VALUES (#date)", con);
sqc.Parameters.AddWithValue("#date", new DateTime(1819, 12, 14));
If you are running this from an interactive batch (SQL Server Management Studio, or similar), use SET LANGUAGE to ensure the dates are parsed correctly:
SET LANGUAGE ENGLISH;
INSERT INTO StateRegion (FullName, Abbreviation, RegionType, Admitted, Capital)
VALUES ('Alabama', 'AL', 1, '1819-Dec-14', 'Montgomery');
SqlFiddle example showing correct parsing
Do not confuse storage format and display format. Just because the server store the date in the database as '1819-12-14' you can use a custom formatting output for the display.
Then correct for the display issue with a function such as:
CREATE FUNCTION usp_FormatedDateString (#Date Date)
RETURNS VARCHAR(50)
AS
BEGIN
DECLARE #RETURN AS VARCHAR(50)
DECLARE #I INT = 0
DECLARE #M AS VARCHAR(100) = 'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'
SET #RETURN = CAST(DATEPART(YEAR,#Date) AS VARCHAR(4))
SET #I = DATEPART(MONTH, #Date) - 1
SET #RETURN = #RETURN + '-' + SUBSTRING(#M,(#I*3)+1,3)+'-'+ CAST (DATEPART(DAY,#Date) AS VARCHAR(2))
RETURN #RETURN
END
GO
Then when you display the results:
SELECT FullName,Abbreviation,RegionType, dbo.usp_FormatedDateString (Admitted) as Admitted, Capital FROM StateRegion
It will display correct and store correctly.
You can try to use an explicit format for the conversion. You are not explaining why you can't change the format, but I imagine that you are reading the values somehow that are already stored as that. You can use CONVERT:
DECLARE #Admitted VARCHAR(11);
SET #Admitted = '1819-Dec-14'
SELECT CONVERT(DATETIME,RIGHT(#Admitted,2)+' '+
SUBSTRING(#Admitted,6,3)+' '+
LEFT(#Admitted,4),106);
Chang datatype of date to VARCHAR

Converting varchar datatype to datetime datatype using SQL 2012 management studio

I have a column which has ddmmmyyyy:hh:mm:ss.nnnnnn it is stored as varchar(25). I need to save it as datetime in the same column. I have tried using
update tablename
set columnname = (SUBSTRING(columnname,1,2) + '-' + SUBSTRING(columnname,3,3) + '-' +
SUBSTRING(columnname,6,4) + ' ' + SUBSTRING(columnname,11,8));
and then
alter table tablename
alter columnname datetime;
but later it shows up the error
Msg 242, Level 16, State 3, Line 1
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
How do I change it any other opinion or any modification for the above query. Please help. Thank you.
As per your given string format, you should use datetime2 data type
Your string format is almost correct, only 1 colon is extra after Year.
If you fix that thing, you can directly cast the varchar field into datetime2. For example first you can replace the extra colon with space by running following query,
UPDATE myTable
SET targetColumn = STUFF ( targetColumn , 10, 1, ' ')
-- ddmmmyyyy:hh:mm:ss.nnnnnn
-- \
-- this colon is extra which is at 10th position
After this you can directly ALTER your table and change the data type to datetime2.
Important: data in all the lines must contain valid date
Here is a test which shows how you can convert
CREATE TABLE testTable(testCol varchar(25));
INSERT INTO testTable(testCol)
VALUES('03Jan2014 18:33:39.999999');
ALTER TABLE testTable ALTER COLUMN testCol datetime2;
SELECT *
FROM testTable
DROP TABLE testTable;
It has already been answered here: Is there a way to convert a varchar to DATETIME in SQL SERVER 2008?
He uses: convert(datetime,'24/05/2012 09:56:06',103)
Although you might have to do some substrings to adapt to a format covered by convert: http://www.sql-server-helper.com/tips/date-formats.aspx
Add a new column
alter table t
add n datetime
Update the new column
update t
set n = datetimefromparts(
cast(substring(o,6,4) as int),
case substring(o,3,3)
when 'jan' then 1
...
when 'dec' then 12
end,
cast(substring(o,1,2) as int),
cast(substring(o,11,2) as int),
cast(substring(o,14,2) as int),
cast(substring(o,17,2) as int),
cast(substring(o,20,6) as int)
)
If you need to drop the old column
alter table t
drop column o

How to enter a Date into a table in TSQL? (Error converting data type varchar to datetime)

I want to enter 30/10/1988 as the date to a DOB column in a table using a procedure
alter procedure addCustomer
#userName varchar(50),
#userNIC varchar(50),
#userPassword varchar(100),
#userDOB datetime,
#userTypeID int,
#userEmail varchar(50),
#userTelephone int,
#userAddress char(100),
#userCityID int,
#status int output
as
declare #userID int
declare #eid int
declare #tid int
declare #aid int
execute getLastRaw 'userID','tblUserParent', #userID output
insert into tblUserParent values (#userID, #userName, #userNIC, #userPassword, #userDOB, #userTypeID)
execute getLastRaw 'addressID','tblAddress', #aid output
insert into tblAddress values (#aid, #userAddress, #userID, #userCityID)
execute getLastRaw 'emailID','tblEmail', #eid output
insert into tblEmail values (#eid, #userEmail, #userID)
execute getLastRaw 'telephoneID','tblTelephoneNO', #tid output
insert into tblTelephoneNO values (#tid, #userTelephone , #userID)
insert into tblUserCustomer values (#userID, #eid , #tid, #aid)
...but it gives an error when i enter like this '30/10/1988'
Msg 8114, Level 16, State 5, Procedure addCustomer, Line 0 Error converting data type varchar to datetime.
...but when I enter like only the 30/10/1988
Incorrect syntax near '/'
How do I fix this?
If you would truly like to avoid the possibility of ambiguous dates based, then you should always enter it in one of the two unambiguous date formats Answer has already been selected and it's valid but I'm a believer in spreading the knowledge ;)
As noticed by #cloud and my post representing a younger, and less wise me with a link only answer, I'll pop the contents of the archive of Jamie Thompson's answer for unambiguous date formats in TSQL
tl;dr;
yyyy-MM-ddTHH24:mi:ss
yyyyMMdd HH24:mi:ss
One of the most commonly used data types in SQL Server is [datetime]
which unfortunately has some vagaries around how values get casted. A
typical method for defining a [datetime] literal is to write it as a
character string and then cast it appropriately. The cast syntax looks
something like this: DECLARE #dt NVARCHAR(19) = '2009-12-08 18:00:00';
SELECT CAST(#dt AS datetime);
Unfortunately in SQL Server 2005 the result of the cast operation may
be dependent on your current language setting. You can discover your
current language setting by executing: SELECT ##LANGUAGE To
demonstrate how your language setting can influence the results of a
cast take a look at the following code: ALTER DATABASE tempdb
SET COMPATIBILITY_LEVEL = 90 ; --Behave like SQL Server 2005
USE tempdb
GO
DECLARE #t TABLE (
dateString NVARCHAR(19)
);
INSERT #t (dateString)
VALUES ('2009-12-08 18:00:00') --'yyyy-MM-dd hh24:mi:ss'
, ('2009-12-08T18:00:00') --'yyyy-MM-ddThh24:mi:ss'
, ('20091208 18:00:00') --'yyyyMMdd hh24:mi:ss'
SET LANGUAGE french;
SELECT 'french' AS lang
, DATENAME(MONTH,q.[dt]) AS mnth
, q.[dt]
FROM (
SELECT CAST(dateString AS DATETIME) AS dt
FROM #t
)q;
SET LANGUAGE us_english;
SELECT 'us_english' AS lang
, DATENAME(MONTH,q.[dt]) AS mnth
, q.[dt]
FROM (
SELECT CAST(dateString AS DATETIME) AS dt
FROM #t
)q; We are taking the value which can be described in words as “6pm on 8th December 2009”, defining it in three different ways, then
seeing how the ##LANGUAGE setting can affect the results. Here are
those results: french language datetime Notice how the interpretation
of the month can change depending on ##LANGUAGE. If
##LANGUAGE=’french’ then the string '2009-12-08 18:00:00' is
interpreted as 12th August 2009 (‘août’ is French for August for those
that don’t know) whereas if ##LANGUAGE=’us_english’ it is interpreted
as 8th December 2009. Clearly this is a problem because the results of
our queries have a dependency on a server-level or connection-level
setting and that is NOT a good thing. Hence I recommend that you only
define [datetime] literals in one of the two unambiguous date formats:
yyyy-MM-ddTHH24:mi:ss yyyyMMdd HH24:mi:ss That was going to be the end
of this blog post but then I found out that this behaviour changed
slightly in SQL Server 2008. Take the following code (see if you can
figure out what the results will be before I tell you): ALTER
DATABASE tempdb
SET COMPATIBILITY_LEVEL = 100 ; --Behave like SQL Server 2008
GO
USE tempdb
GO
SET LANGUAGE french;
DECLARE #dt NCHAR(10) = '2009-12-08 18:00:00'; --Ambiguous date
format
SELECT CAST(#dt AS datetime) AS [ExplicitCast]
, DATENAME(MONTH,#dt) AS [MonthFromImplicitCast]
, DATENAME(MONTH,CAST(#dt AS datetime)) AS
[MonthFromExplicitCast]; Here we are doing three different things with
our nchar literal: explicitly cast it as a [datetime] extract the
month name from the char literal using the DATENAME function (which
results in an under-the-covers implicit cast) extract the month name
from the char literal using the DATENAME function after it has been
explicitly casted as a [datetime] Note that the compatibility level is
set to SQL Server 2008 and ##LANGUAGE=’french’. Here are the results:
image (Were you correct?) Let’s take a look at what is happening here.
The behaviour when we are explicitly casting as [datetime] hasn’t
changed, our nchar literal is still getting interpreted as 12th August
rather than 8th December when ##LANGUAGE=’french’. The
[MonthFromExplicitCast] field is interesting though, it seems as
though the implicit cast has resulted in the desired value of 8th
December. Why is that? To get the answer we can turn to BOL’s
description of the DATENAME function syntax: image The implicit cast
is not casting to [datetime] at all, it is actually casting to [date]
which is a new datatype in SQL Server 2008. The new date-related
datatypes in SQL Server 2008 (i.e. [date], [datetime2], [time],
[datetimeoffset]) disregard ##LANGUAGE and hence we get behaviour that
is more predictable and, frankly, better. These new behaviours for SQL
Server 2008 were unknown to me when I began this blog post so I have
learnt something in the course of authoring it, I hope it has helped
you too. No doubt someone somewhere is going to get nastily burnt by
this at some point, make sure that it isn’t you by always using
unambiguous date formats: yyyy-MM-ddTHH24:mi:ss yyyyMMdd HH24:mi:ss
regardless of which version you are on!
The following works in both SQL Server and MySql without ambiguity: yyyy-mm-dd, like so:
INSERT INTO TableName(DateColumn) VALUES ('1988-10-30');
...as an added benefit there's no question of whether it's a US or European style date on days like the fourth of March...
See if there is a culture setting that you can change to allow you to use dd/mm/yyyy. I believe it is expecting mm/dd/yyyy.
A potentially easy way around the problem is to use a date format with no ambiguity between mm/dd/yyyy and dd/mm/yyyy such as dd-mmm-yyyy, eg: 30-OCT-1988