2014-01-29 51 views
1

我遇到一个真正的问题,从SQL Server获取日期为Oracle,同时保持正确的值。如何从SQL Server获取日期到Oracle 12c?日期正在倒置(倒退)

在SQL Server中的值是这样的:"Apr 28 1969 12:00AM" 当我拉这个数值为.NET日期时间它看起来像:"04/28/1969 12:00AM" 当它被插入到Oracle,它看起来像:“28-APR-19”

Oracle日期看起来很正确,但如果我做了TO_CHAR(DATE, 'MM/DD/YYYY'),我会得到“04/28/6919”< ----今年倒退!

这里有一组日期从Oracle:

01/18/5919 
09/19/8819 
02/13/5619 
08/30/5819 
04/28/6519 
08/22/6919 
10/24/6119 
02/27/6919 
02/28/6019 
12/20/6219 
09/28/3619 
10/02/6219 

所有年年底在“19”,因为他们都是倒退!

因为Oracle自以为我多年的每一个与“19”,它认为所有闰年是无效的,我有一个大的数据集的我甚至不能得到插入(更不用提劣枣)

结束

我使用一个简单的存储过程从SQL Server中获取数据,然后将数据存储在一个简单的POCO中。我使用Oracle.DataAccess.OracleBulkCopy来使用DataTable进行我的实际插入。我无法控制如何检索数据或如何保存数据......但我可以在两者之间进行操作。

到目前为止,我已经尝试将日期作为字符串返回,并对其进行格式设置(dd-MMM-yyyy)和(yyyymmdd) - 都无效。我也试着将日期设置为空,如果它是一个闰年,并试图直接设置它...这是一个黑客攻击,但这也没有任何好处。

任何帮助表示赞赏。

我的存储过程:

USE [InsuranceFileProcessing] GO SET ANSI_NULLS OFF GO SET QUOTED_IDENTIFIER OFF GO ALTER PROCEDURE [DBO] [P_GET_INSURANCE_POLICY_HOLDERS_FOR_DATA_UPLOAD] @INSURANCE_COMPANY_CODE VARCHAR(5) 。 ,@ INSURANCE_FILE_UPLOAD_LOG_ID INT ,@START_ROW_NUM INT ,@END_ROW_NUM INT ,@GET_LEAP_YEARS BIT AS BEGIN DECLARE @ERROR_NUMBER INT DECLARE INT @ERROR_SEVERITY DECLARE INT @ERROR_STATE DECLARE NVARCHAR @ERROR_PROCEDURE(100) DECLARE @ERROR_LINE INT DECLARE NVARCHAR @ERROR_MESSAGE(4000)

SET NOCOUNT ON 

BEGIN 
    BEGIN TRY 
      SELECT DISTINCT     
       IT.INSURANCE_COMPANY_CODE    INS_COMPANY_NUM 
      , IP.POLICY_NUMBER       INS_POLICY_NUM    
      , PH.FIRST_NAME        PH_FIRST_NAME 
      , PH.MIDDLE_NAME       PH_MIDDLE_NAME 
      , PH.LAST_NAME        PH_LAST_NAME 
      , LEFT(PH.NAME_SUFFIX,1)     PH_NAME_SUFFIX 
      , PH.ADDRESS        PH_ADDRESS 
      , PH.CITY         PH_CITY 
      , PH.STATE         PH_STATE 
      , PH.ZIPCODE        PH_ZIP_CODE 
      , CONVERT(VARCHAR, PH.DOB, 100)    PH_DATE_OF_BIRTH 
      , PH.GENDER         PH_GENDER 
      , PH.FL_DLN         INS_DL_NUMBER    
      , PH.FED_TIN        INS_FEID 
      , PH.FL_DLN_CROSS_REF      FL_DLN_CROSS_REF 
      , PH.FL_DLN_GENERATED      FL_DLN_GENERATED 
      , PH.NON_STRUCTURED_NAME     PH_NON_STRUCT_NAME 
      , PH.EFFECTIVE_DATE       EFFECTIVE_DATE  
      , (CASE PH.COMPANY_INDICATOR 
       WHEN 'Y' THEN 'F'         
       WHEN 'N' THEN 'T' 
       ELSE 'T' 
       END)         PERSONAL_FLAG   
      --, CONVERT(VARCHAR(12),IP.UPDATE_TS,110)  INSERT_TIMESTAMP  
      , IP.CREATED_TS        INSERT_TIMESTAMP  
      , IDENTITY(INT,1,1) AS      ROWNUM 
      , ph.CUSTOMER_NUMBER      CUSTOMER_NUMBER 


      INTO 
          #UPLOAD_POLICY_HOLDER 

      FROM INSURANCE_TRANSACTION IT 
       INNER JOIN INSURANCE_COMPANIES IC ON IC.INSURANCE_COMPANY_ID = IT.INSURANCE_COMPANY_ID 
       INNER JOIN INSURANCE_POLICY IP ON IT.INSURANCE_POLICY_ID = IP.INSURANCE_POLICY_ID 
       INNER JOIN POLICY_HOLDER PH ON IP.INSURANCE_POLICY_ID = PH.INSURANCE_POLICY_ID    
      WHERE IT.INSURANCE_COMPANY_CODE  = @INSURANCE_COMPANY_CODE 
       AND IT.INSURANCE_FILE_UPLOAD_LOG_ID = @INSURANCE_FILE_UPLOAD_LOG_ID 
       AND IT.HAS_ERROR = 0 
       AND PH.HAS_ERROR = 0 
       AND ((LEFT(REPLACE(CONVERT(VARCHAR(10), DOB, 101), '/', ''), 4) = '0229' AND @GET_LEAP_YEARS = 1) 
        OR (LEFT(REPLACE(CONVERT(VARCHAR(10), DOB, 101), '/', ''), 4) <> '0229' AND @GET_LEAP_YEARS = 0)) 
      ORDER BY IT.INSURANCE_COMPANY_CODE , IP.POLICY_NUMBER ; 

      SELECT * FROM #UPLOAD_POLICY_HOLDER 
        WHERE ROWNUM > @START_ROW_NUM AND ROWNUM <= @END_ROW_NUM 
        ORDER BY ROWNUM; 

        IF EXISTS 
        (
        SELECT * 
        FROM tempdb.dbo.sysobjects 
        WHERE ID = OBJECT_ID(N'tempdb..#UPLOAD_POLICY_HOLDER') 
        ) 
        BEGIN 
          DROP TABLE #UPLOAD_POLICY_HOLDER 
        END 


    END TRY 

    BEGIN CATCH 
     IF @@TRANCOUNT > 0 
      ROLLBACK TRANSACTION 

      SET @ERROR_NUMBER = ERROR_NUMBER() 
      SET @ERROR_SEVERITY = ERROR_SEVERITY() 
      SET @ERROR_STATE = ERROR_STATE() 
      SET @ERROR_PROCEDURE = ERROR_PROCEDURE() 
      SET @ERROR_LINE = ERROR_LINE() 
      SET @ERROR_MESSAGE = ERROR_MESSAGE() 

      EXEC P_INSERT_SQL_ERROR @ERROR_NUMBER, @ERROR_SEVERITY, @ERROR_STATE, @ERROR_PROCEDURE, @ERROR_LINE, @ERROR_MESSAGE 
    END CATCH 

END 

END

你可以忽略Leap_Year的东西 - 这是我做的一个单独的尝试。 PH.DOB字段是我遇到的问题。以前我只是返回DOB字段,CONVERT()是我试图将值作为一个字符串来获得,所以我可以有更多的控制权。

我插入到Oracle代码:

私人无效LoadDataIntoHSMVDBBulk(DataTable的DT,串DestinationTableName,列表ColumnMappings) { 使用(VAR BC =新OracleBulkCopy(GetConnectionString())) { BC。 DestinationTableName = DestinationTableName; bc.BulkCopyOptions = OracleBulkCopyOptions.UseInternalTransaction;

  foreach (var colmapping in ColumnMappings) 
      { 
       var split = colmapping.Split(new[] { ',' }); 
       bc.ColumnMappings.Add(split.First(), split.Last()); 
      } 

      bc.BulkCopyTimeout = 20000; 
      bc.BatchSize = GetOracleBulkCountFromConfig(); 
      bc.NotifyAfter = GetOracleBulkCountFromConfig(); 
      bc.OracleRowsCopied += new OracleRowsCopiedEventHandler(bulkCopy_OracleRowsCopied); 
      bc.WriteToServer(dt); 
      bc.Close(); 
      bc.Dispose(); 
      dt.Clear(); 
     } 
    } 

我把我们的项目的旧副本从几个月前和日期是正确的!看来罪魁祸首是我们的Oracle.DataAccess版本。当我指向Oracle 11g时,日期是好的,当我指向新的Oracle 12c时,日期反转了。任何帮助表示赞赏,但现在我们将服务器回滚到11g。

+2

请显示您的代码插入到oracle! – OldProgrammer

+0

和你的代码从sql中获取该日期。请记住,您始终可以使用此:http://msdn.microsoft.com/pt-br/library/ms187928.aspx –

+4

理想情况下,请不要在所有*处使用字符串表示法*。作为DateTime获取,插入为DateTime ... –

回答

1

这对我们来说也是一个问题,无法解决。

我们已经找到解决方法,虽然这不是漂亮,但工程。并不是一个巨大的时间消费者。 我们关闭bulkCopy,成功后我们更新日期类型列。更新不应该花太长时间,这是一个批量操作。

希望这会有所帮助。干杯!

//EF 5.0.0. 
private tables entities = new Tables(); 
private string validFrom; //try with date as well, should work 
private int id; 
using (OracleBulkCopy bulkCopy = new OracleBulkCopy(applicationContext.GetConnection(CrmContext.ConnectionEnum.CrmDatabase))) 
{ 
      bulkCopy.DestinationTableName = "TABLE"; 
      bulkCopy.BulkCopyTimeout = 180; 
      bulkCopy.WriteToServer(dataTable); 
      bulkCopy.Close(); 
} 
//this is a workaroud due to error in Oracle DataAccess Driver 
//look at the 
entities.Database.ExecuteSqlCommand("UPDATE TABLE SET DATE_FROM = TO_DATE(:p0,'DD.MM.YYYY.') WHERE ID = :p1", validFrom, id); 
entities.SaveChanges(); 
+0

有没有简单的方法来确保你只更新你刚插入的记录?我计划尽快试用 - 谢谢! – BrianLegg