我有一个Oracle数据库,其中包含一些我想要移动到SQL Server的数据。
问题是我的Oracle DB有一些类型为TIMESTAMP(0) WITH TIME ZONE
的列,而SSIS检测到的是CLOB
。因此它无法说它无法将CLOB
转换为datetime2
。
我已经在SQL Server数据库中创建了表。所以它只是通过一些类型转换来移动数据。
我正在使用SQL Server Management Studio(SSMS)中的SQL Server导入和导出向导(SSIS)。
我正在使用.NET Framework Data Provider for Oracle连接到Oracle DB和SQL Server Native Client 11.0以连接到我的SQL Server。
我的源类型是TIMESTAMP(0) WITH TIME ZONE
,我的目的地类型是datetime2
。
这是我得到的错误:
[Source Information]
Source Location : localhost
Table: "MYSPACE"."MYTABLE"
Column: START_DATE
Column Type: CLOB
SSIS Type: Unicode text stream [DT_NTEXT]
Mapping file (to SSIS type): C:\Program Files (x86)\Microsoft SQL Server\140\DTS\MappingFiles\OracleClientToSSIS10.XML
[Destination Information]
Destination Location : localhost
Destination Provider : SQLNCLI11
Table: [dbo].[mytable]
Column: start_date
Column Type: datetime2
SSIS Type: database timestamp with precision [DT_DBTIMESTAMP2]
Mapping file (to SSIS type): C:\Program Files (x86)\Microsoft SQL Server\140\DTS\MappingFiles\MSSQLToSSIS10.XML
[Conversion Steps]
Conversion unknown ...
SSIS conversion file: C:\Program Files (x86)\Microsoft SQL Server\140\DTS\binn\DtwTypeConversion.xml
因此,您可以看到START_DATE
列被检测为CLOB。这是不正确的。
我查看了OracleClientToSSIS10.XML
<!-- TIMESTAMP 10.* -->
<dtm:DataTypeMapping >
<dtm:SourceDataType>
<dtm:DataTypeName>timestamp</dtm:DataTypeName>
</dtm:SourceDataType>
<dtm:DestinationDataType>
<dtm:NumericType>
<dtm:DataTypeName>DT_DBTIMESTAMP2</dtm:DataTypeName>
<dtm:SkipPrecision/>
<dtm:UseSourceScale/>
</dtm:NumericType>
</dtm:DestinationDataType>
</dtm:DataTypeMapping>
<!-- TIMESTAMP WITH TIME ZONE 10.* -->
<dtm:DataTypeMapping >
<dtm:SourceDataType>
<dtm:DataTypeName>TIMESTAMP WITH TIME ZONE</dtm:DataTypeName>
</dtm:SourceDataType>
<dtm:DestinationDataType>
<dtm:NumericType>
<dtm:DataTypeName>DT_DBTIMESTAMPOFFSET</dtm:DataTypeName>
<dtm:SkipPrecision/>
<dtm:UseSourceScale/>
</dtm:NumericType>
</dtm:DestinationDataType>
</dtm:DataTypeMapping>
<!-- CLOB -->
<dtm:DataTypeMapping >
<dtm:SourceDataType>
<dtm:DataTypeName>CLOB</dtm:DataTypeName>
</dtm:SourceDataType>
<dtm:DestinationDataType>
<dtm:CharacterStringType>
<dtm:DataTypeName>DT_NTEXT</dtm:DataTypeName>
<dtm:Length>255</dtm:Length>
</dtm:CharacterStringType>
</dtm:DestinationDataType>
</dtm:DataTypeMapping>
看起来很好,对吗?
处理Oracle格式的date-ish数据类型时遇到了类似的问题。我发现可行的方法是在将数据转换为Oracle之前将数据转换为字符串。然后,一旦将数据导入SQL Server,就可以对数据进行转换。
您需要修改导入/导出向导以使用查询来指定要从Oracle服务器获取的数据。作为源查询的一部分,您可以执行以下转换:
SELECT
CAST("START_DATE" AS VARCHAR2(26)) AS "StartDate"
FROM MYSPACE.MYTABLE
然后在SQL Server中,您可以转换为这样的日期时间:
SELECT CAST(CONVERT(DATETIMEOFFSET, StartDate) AS DATETIME)
如果您使用的是SQL Server 2016或更高版本,则可以使用AT TIME ZONE
和本地时区来获取调整后的日期时间值:
SELECT CAST(CONVERT(DATETIMEOFFSET, StartDate) AT TIME ZONE 'Pacific Standard Time' AS DATETIME)
我无法让任何驱动程序为日期列工作。
所以我最终进入SQL Developer并将带有date列的表导出到INSERT语句,然后运行regex replace。
娱乐时间 :(