当DateTime与文本连在一起时,Oracle导出MD5不正确。

问题描述 投票:0回答:2

请考虑在Oracle 12c上使用这个SQL

select to_date('01-02-2020','MM-DD-YYYY'),
standard_hash (to_date('01-02-2020','MM-DD-YYYY'), 'MD5') Only_Date_MD5,
to_date('01-02-2020 12:34:56','MM-DD-YYYY HH:MI:SS'),
standard_hash (to_date('01-02-2020 12:34:56','MM-DD-YYYY HH:MI:SS'), 'MD5') DateTime_MD5,
standard_hash (to_date('01-02-2020','MM-DD-YYYY') || 'SomeText', 'MD5') Date_Concat_Text_MD5,
standard_hash (to_date('01-02-2020 12:34:56','MM-DD-YYYY HH:MI:SS') || 'SomeText', 'MD5') DateTime_Concat_Text_MD5
from dual;

产量

SOME_DATE                   01/02/2020
ONLY_SOME_DATE_MD5          6D44D021F4D2CACA3DBEC6E88AEEB7AD
SOME_DATETIME               01/02/2020 12:34:56
SOME_DATETIME_MD5           F8FDBBC5181E79B99A1EE13CB71A1D46
DATE_CONCAT_TEXT_MD5        **FE7DA8E96A7233A33F03CC592A929011**
DATETIME_CONCAT_TEXT_MD5    **FE7DA8E96A7233A33F03CC592A929011**

为什么Oracle MD5对与文本连接的Date和与文本连接的DateTime(具有相同日期)返回相同的值。它在导出MD5时丢弃了DateTime的时间部分。

sql oracle md5
2个回答
1
投票

这与以下内容无关 standard_hash(). 这个问题是一个隐性的转换。date 到一个字符串。

当你把一个 date 隐性 到一个字符串(或使用 to_char() 没有格式),那么结果只有日期部分。 所以这个

select to_date('01-02-2020 12:34:56', 'MM-DD-YYYY HH:MI:SS') || 'abc'
from dual

返回:

02-JAN-20abc

对于你的目的,我强烈建议使用 to_char() 来转换回更详细的表示。 您也可以使用 to_timestamp() 而不是--默认的表示方式将包括时间。

所以。

select to_timestamp('01-02-2020 12:34:56', 'MM-DD-YYYY HH:MI:SS') || 'abc'
from dual

返回。

02-JAN-20 12.34.56.000000000abc

0
投票

一个好的做法(或者可能是一个 变通办法)至 计算哈希码 在这一步之前,明确地将NLS设置为最有覆盖力的选项,以实现不同数据类型的连列(这将不可避免地导致数据类型的转换)。

例子

ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ',.';
ALTER SESSION SET NLS_DATE_FORMAT = 'DD.MM.YYYY HH24:MI:SS';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'DD.MM.YYYY HH24:MI:SSXFF';
ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'DD.MM.YYYY HH24:MI:SSXFF TZR';

这将 1) 不 吃光 部分数据 在转换和 2)将产生一个确定性的结果 独立于会话设置。

您可能需要存储之前的值,并在连接后恢复它们。

这一步将确保样本数据的预期结果。

其它 你应该考虑的是使用 特殊连接定界符 的字符串 不出现在数据中)

例子

 col1||chr(10)||col1 

这将确保两行与 col1 NULL, col2 'A'col1 'A', col2 NULL 会产生 不同 连接后的哈希码。

© www.soinside.com 2019 - 2024. All rights reserved.