ORA-01840: 使用 Select 的 Oracle 插入中的日期格式输入值不够长

Posted

技术标签:

【中文标题】ORA-01840: 使用 Select 的 Oracle 插入中的日期格式输入值不够长【英文标题】:ORA-01840: input value not long enough for date format in Oracle Insert using Select 【发布时间】:2018-01-17 08:35:38 【问题描述】:

我有以下查询我收到错误为ORA-01840: input value not long enough for date formatC_DATE 列是日期数据类型。

INSERT INTO CS_LOG(NAME, ID, C_DATE)
Select MAX(ML.NAME), ML.ID, TO_CHAR(CHK_DATE,'YYYYMM')
from D_ID ML,
     CS_LOG MD
WHERE ML.NAME != MD.NAME
  and ML.ID != MD.ID
  and MD.C_DATE = LAST_DAY(to_date(sysdate,'YYYYMMDD'))
GROUP BY ML.ID, C_DATE;

【问题讨论】:

sysdate 应该是一个日期。尝试直接应用last_day函数 单独的select 声明如何?如果你在没有插入的情况下执行,你会收到错误? 单独选择语句在没有插入的情况下工作 那么我们需要目标表和源表的结构。请提供 ddl 那么chk_date是什么数据类型?听起来像是 varchar,需要显式转换为具有合适格式掩码的日期? (如前所述,即使当前有效,也不要执行 to_date(sysdate...),这是没有意义的,并且会因不同的 NLS 设置而中断。) 【参考方案1】:

您不能插入带有“格式”的日期。日期具有内部表示,它们始终具有所有日期/时间组件,然后可以根据需要进行格式化以进行显示。

您生成为 YYYYMM 的字符串正在被插入隐式转换为日期,因为那是目标列的数据类型。该隐式转换正在使用您的 NLS 设置,因此需要更长的值来匹配 NLS 日期格式。您的字符串与该隐式格式不匹配,这会导致您看到的错误。

如果您只对年份和月份感兴趣,那么最接近的方法是存储每月第一天的午夜,您可以通过 trunc 获得:

INSERT INTO CS_LOG(NAME, ID, C_DATE)
Select MAX(ML.NAME), ML.ID, TRUNC(CHK_DATE,'MM')
from D_ID ML,CS_LOG MD
WHERE ML.NAME != MD.NAME and ML.ID != MD.ID
and MD.C_DATE = LAST_DAY(sysdate)
GROUP BY ML.ID,C_DATE;

我还删除了额外的 to_date 调用。您也应该考虑切换到 ANSI 连接语法。

然后,您可以将 c_date 格式化为 YYYYMM,以便在查询时显示,如果您需要,请通过 to_char

【讨论】:

【参考方案2】:

您正在尝试插入日期,即 YYYYMM 的 varchar 这是正常的,你有一个错误。

尝试插入一个真实的日期,而不仅仅是月份和年份

【讨论】:

实际上我只想插入该格式。不可能吗? TO_CHAR(CHK_DATE,'YYYY-MM-01') 没有。这不可能。这是没有意义的。日期是日期。输出格式是装饰性的,只应在您检索信息时在您的选择查询中更改 如果你想以特定格式存储它,那么它是一个字符串,而不是一个日期

以上是关于ORA-01840: 使用 Select 的 Oracle 插入中的日期格式输入值不够长的主要内容,如果未能解决你的问题,请参考以下文章

数据库操作select语句使用and和or操作符计算次序问题

django:一起使用 select_related 和 get_object_or_404

pandas使用或关系(or)构成组合逻辑筛选dataframe中的满足条件的数据行(use or clause to select dataframe rows)

MySQL使用select in or子句的结果[重复]

MySQL 查询优化:IN() 与 OR

MySQL 2 SQL数据使用(检索排序过滤:SELECT/FROM/LIMIT/ORDER BY/DESC/WHERE/AND/OR/IN/NOT)