2014-01-29 52 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