ORA-01841 发生在一个环境但不是所有
ORA-01841 happens on one environment but not all
我的 (SAP IdM) 应用程序中有以下 SQL 代码:
Select mcmskeyvalue as MKV,v1.searchvalue as STARTDATE, v2.avalue as Running_Changes_flag
from idmv_entry_simple
inner join idmv_value_basic_active v1 on mskey = mcmskey and attrname = 'Start_of_company_change'
and mcentrytype = 'MX_PERSON' and to_date(v1.searchvalue,'YYYY-MM-DD')<= sysdate+3
left join idmv_value_basic v2 on v2.mskey = mcmskey and v2.attrname = 'Running_Changes_flag'
where mcmskey not in (Select mskey from idmv_value_basic_active where attrname = 'Company_change_running_flag')
我已经找到了 ORA-01841 问题的解决方案,因为它可能是类似于此处提到的 MSSQLs try_to_date 的解决方案:How to handle to_date exceptions in a SELECT statment to ignore those rows?
或者我将代码更改为类似这样的解决方案,以仅处理字符串:
Select mcmskeyvalue as MKV,v1.searchvalue as STARTDATE, v2.avalue as Running_Changes_flag
from idmv_entry_simple
inner join idmv_value_basic_active v1 on mskey = mcmskey and attrname = 'Start_of_company_change'
and mcentrytype = 'MX_PERSON' and v1.searchvalue<= to_char(sysdate+3,'YYYY-MM-DD')
left join idmv_value_basic v2 on v2.mskey = mcmskey and v2.attrname = 'Running_Changes_flag'
where mcmskey not in (Select mskey from idmv_value_basic_active where attrname = 'Company_change_running_flag')
所以对于实际问题我有一个解决方案。
但现在我开始与我的客户和队友讨论为什么会发生错误。
基本上对于符合“attrname = 'Start_of_company_change'”要求的 idmv_value_basic_activ 的所有条目,我们可以确定这些是日期。此外,如果我们执行查询以检查将要传递的所有值,则所有值均采用有效格式。
我在大学里了解到,DB 引擎可以决定 运行 查询的各个部分的顺序。所以对我来说最合乎逻辑的解释是,在开发环境(我们遇到问题的地方)上,“ to_date(v1.searchvalue,'YYYY-MM-DD')<= sysdate+3”部分在“attrname = 'Start_of_company_change'”部分之前执行
而在生产环境中,一切都像魅力一样,段按照 SQL 语句描述的顺序执行。
现在我的问题是:
第一:我没记错吧,因为老师只说过一次,当时我真的听不懂
其次:我的这个假设是正确的还是有其他问题的原因?
边界信息:
该工具使用一种移位数据结构,这就是为什么 idmv_value_basic_activ 视图的实际“Searchvalue”列中可以有很多不同类型的原因。数据库层的数据类型总是varchar。
“数据库引擎可以决定 运行 查询的各个部分的顺序”
这是正确的。 SQL 查询只是对所需数据及其存储位置的描述。 Oracle 将计算一个执行计划以尽可能地检索该数据。该计划将根据许多因素而有所不同,例如 table 中的实际行数和索引的存在,因此它会因环境而异。
听起来您的 table 中某处的日期无效,因此 to_date
引发异常。您可以使用 validate_conversion
找到它。
我的 (SAP IdM) 应用程序中有以下 SQL 代码:
Select mcmskeyvalue as MKV,v1.searchvalue as STARTDATE, v2.avalue as Running_Changes_flag
from idmv_entry_simple
inner join idmv_value_basic_active v1 on mskey = mcmskey and attrname = 'Start_of_company_change'
and mcentrytype = 'MX_PERSON' and to_date(v1.searchvalue,'YYYY-MM-DD')<= sysdate+3
left join idmv_value_basic v2 on v2.mskey = mcmskey and v2.attrname = 'Running_Changes_flag'
where mcmskey not in (Select mskey from idmv_value_basic_active where attrname = 'Company_change_running_flag')
我已经找到了 ORA-01841 问题的解决方案,因为它可能是类似于此处提到的 MSSQLs try_to_date 的解决方案:How to handle to_date exceptions in a SELECT statment to ignore those rows?
或者我将代码更改为类似这样的解决方案,以仅处理字符串:
Select mcmskeyvalue as MKV,v1.searchvalue as STARTDATE, v2.avalue as Running_Changes_flag
from idmv_entry_simple
inner join idmv_value_basic_active v1 on mskey = mcmskey and attrname = 'Start_of_company_change'
and mcentrytype = 'MX_PERSON' and v1.searchvalue<= to_char(sysdate+3,'YYYY-MM-DD')
left join idmv_value_basic v2 on v2.mskey = mcmskey and v2.attrname = 'Running_Changes_flag'
where mcmskey not in (Select mskey from idmv_value_basic_active where attrname = 'Company_change_running_flag')
所以对于实际问题我有一个解决方案。
但现在我开始与我的客户和队友讨论为什么会发生错误。
基本上对于符合“attrname = 'Start_of_company_change'”要求的 idmv_value_basic_activ 的所有条目,我们可以确定这些是日期。此外,如果我们执行查询以检查将要传递的所有值,则所有值均采用有效格式。
我在大学里了解到,DB 引擎可以决定 运行 查询的各个部分的顺序。所以对我来说最合乎逻辑的解释是,在开发环境(我们遇到问题的地方)上,“ to_date(v1.searchvalue,'YYYY-MM-DD')<= sysdate+3”部分在“attrname = 'Start_of_company_change'”部分之前执行
而在生产环境中,一切都像魅力一样,段按照 SQL 语句描述的顺序执行。
现在我的问题是:
第一:我没记错吧,因为老师只说过一次,当时我真的听不懂
其次:我的这个假设是正确的还是有其他问题的原因?
边界信息:
该工具使用一种移位数据结构,这就是为什么 idmv_value_basic_activ 视图的实际“Searchvalue”列中可以有很多不同类型的原因。数据库层的数据类型总是varchar。
“数据库引擎可以决定 运行 查询的各个部分的顺序”
这是正确的。 SQL 查询只是对所需数据及其存储位置的描述。 Oracle 将计算一个执行计划以尽可能地检索该数据。该计划将根据许多因素而有所不同,例如 table 中的实际行数和索引的存在,因此它会因环境而异。
听起来您的 table 中某处的日期无效,因此 to_date
引发异常。您可以使用 validate_conversion
找到它。