[英]How can I get a date from SQL Server into Oracle 12c? Dates are being inverted (backwards)
我遇到了一个真正的问题,那就是在保持正确值的同时从SQL Server
到Oracle
的日期。
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.