繁体   English   中英

如何从SQL Server获取到Oracle 12c的日期? 日期正在倒转(向后)

[英]How can I get a date from SQL Server into Oracle 12c? Dates are being inverted (backwards)

我遇到了一个真正的问题,那就是在保持正确值的同时从SQL ServerOracle的日期。

SQL Server中的值看起来像: "Apr 28 1969 12:00AM"当我将该值拉入.NET DateTime时,它看起来像是: "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”结尾,所以它认为所有的leap年都是无效的,并且我拥有大量的数据,甚至无法插入(更不用说错误的日期了)

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

到目前为止,我尝试过将日期作为字符串返回并对其进行格式化( dd-MMM-yyyy )和( yyyymmdd )-均yyyymmdd 我还尝试将日期设置为null(如果是it年),然后尝试直接将其设置为……这是一个hack,但这也没有任何好处。

任何帮助表示赞赏。

我的存储过程:

USE [InsuranceFileProcessing] GO SET ANSI_NULLS关GO SET QUOTED_IDENTIFIER OFF GO ALTER PROCEEDURE [dbo]。宣告@ERROR_SEVERITY INT宣告@ERROR_STATE INT宣告@ERROR_PROCEDURE NVARCHAR(100)宣告@ERROR_LINE INT宣告@ERROR_MESSAGE NVARCHAR(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 

结束

您可以忽略Leap_Year的内容-这是我做过的另一次尝试。 PH.DOB字段是我遇到的问题。 以前我只是返回DOB字段,所以CONVERT()是我尝试将值作为字符串获取,以便可以进行更多控制。

我插入Oracle代码:

私人无效LoadDataIntoHSMVDBBulk(DataTable dt,字符串DestinationTableName,列表列映射){使用(var bc = new 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。

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

我们已经找到了解决方法,尽管它并不漂亮,但是可以解决。 而且不是一个巨大的时间消耗者。 我们批量关闭并在成功后对日期类型列进行更新。 更新不应花费太长时间,这是一项批量操作。

希望这可以帮助。 干杯!

//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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM