将Oracle TIMESTAMP(6)转换为SQL SERVER 2008 DATETIME2(6)

时间:2015-01-20 09:18:01

标签: sql sql-server sql-server-2008

我将csv文件批量导入SQL Server 2008,csv文件是从Oracle SQL开发人员导出表数据生成的。 该csv文件中一列的数据位于TIMESTAMP(6)中,我为SQL Server 2008中的所需列提供了DATETIME2(6)数据类型。 我正在使用以下声明导入CSV文件

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

在执行上述操作时遇到以下错误 Msg 4864,Level 16,State 1,Line 1 第1行第5列(CREATED_DATE)的批量加载数据转换错误(类型不匹配或指定代码页的无效字符)。 Msg 4864,Level 16,State 1,Line 1

错误中提到的列中的示例数据如下 21-NOV-14 08.57.51.565214000 AM

所以我正在寻找答案,它可以在批量插入语句或任何可以将样本数据中的日期时间正确转换为SQL SERVER 2008 datetime2格式的转换函数中解决此问题与任何其他属性。

4 个答案:

答案 0 :(得分:1)

SQL Server不知道如何转换文本值" 21-NOV-14 08.57.51.565214000 AM"到DATETIME2列。在查询分析器窗口中尝试:

SELECT CAST('21-NOV-14 08.57.51.565214000 AM' AS DATETIME2(6))

请注意,如果您正在使用DATETIME2(6),那么与您尝试导入的内容相比,它将失去精确度。看看http://msdn.microsoft.com/en-GB/library/bb677335.aspx

当我必须从DB2文本文件中做到这一点时,我已经采用了两种不同的方式。

  1. 将日期时间字段导入varchar,然后编写一些SQL来将字符串操作为SQL Server可识别的格式,如下所示。有点慢和笨重,特别是如果你有很多数据。
  2. 使用SSIS并创建转换以在那里进行字符串操作。这样做的优点是仍然可以批量插入到目标表中,但这意味着您需要能够访问集成服务。

答案 1 :(得分:0)

由于我找不到任何可以为我工作的批量插入,我采用了不同的方法。经过演员和转换的许多小道后,我按照下面的方法工作,按预期工作 我创建了一个函数,可以将oracle timestamp(6)转换为sql的nvarchar,可以直接在sql server 2008中作为datetime2(6)数据类型插入。下面是函数 然后我使用了一个存储过程,它可以接受文件路径作为输入参数,并使用临时表来保存基于nvarchar的datetime2值。在存储过程中,我使用动态批量插入语句插入到所需的表中。该过程在函数

之后
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

执行我已使用以下陈述的陈述

EXEC H_CLAIMS.DBO.IMPORT_APPLICATION_QUEUES @PATH='D:\my_export.CSV';

答案 2 :(得分:0)

确保在执行存储过程时将.csv文件放在服务器计算机驱动器中

答案 3 :(得分:0)

我可能来不及回答这个问题,但是请允许我给我解决方法(如果精度真的不重要) 我从Oracle表将时间戳导入SQL 2008 varchar,然后将varchar更新为适合datetime2的格式,然后将SQL表列更改为数据类型datetime2。 EG:如果您有时间戳记,例如'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;