【问题标题】:Not a valid Month Error while Inserting timestamp value '2021-08-31T16:30:01.850'插入时间戳值“2021-08-31T16:30:01.850”时出现无效月份错误
【发布时间】:2021-11-16 17:27:55
【问题描述】:

插入时间戳值“2021-08-31T16:30:01.850”时出错

INSERT INTO tbl_Account_Master (Account_ID, Verified_Date) 
VALUES (1, '2021-08-31T16:30:01.850')

表定义:

CREATE TABLE tbl_Account_Master 
(
    Account_ID Number(10) NOT NULL,
    Verified_Date Timestamp(3) NULL 
)

错误:

ORA-01843: 月份无效

谢谢

【问题讨论】:

  • 我不是 Oracle 人,但我认为 '31-AUG-2021 16:30:01.850' 或许可以工作。
  • 您的代码假定nls_date_format 会话变量的一个非常具体的值。您的应用程序是否进行了相应设置?
  • 我的数据脚本只有 '2021-08-31T16:30:01.850'。
  • 这个值从何而来?如果可能,请使用时间戳参数而不是字符串

标签: sql oracle


【解决方案1】:

在处理日期和时间戳时不要使用字符串。

'2021-08-31T16:30:01.850'

是一个字符串。它包含我记得我在 SQL Server 中看到的时间戳格式。

以下是标准 SQL 和 Oracle 中的有效时间戳文字:

timestamp '2021-08-31 16:30:01.850'

因此:

INSERT INTO tbl_Account_Master (Account_ID, Verified_Date) 
VALUES (1, TIMESTAMP '2021-08-31 16:30:01.850')

【讨论】:

  • 请注意,“2021-08-31T16:30:01.850”是符合 ISO 8601(日期/时间标准)的有效时间戳。但是,它不是有效的 ISO SQL 格式。
  • SQL Server 也不需要T 分隔符,并且可以与2021-08-31 16:30:01.850' 配合使用。旧版本的 ISO8601 省略了 T 分隔符,但 since 2019 需要 T。也许较新版本的 Oracle 也可以处理当前的 ISO8601 格式?
  • @PanagiotisKanavos 日期的 ISO 标准是 ISO8601。 SQL 的 ISO 标准是 ISO/IEC 9075,它将时间戳文字格式指定为 TIMESTAMP '2011-07-01 00:00:00.000000000'(小数秒是可选的)。如果其他 RDBMS 支持 T 而不是时间戳文字中的空格,那么它在 ISO9075 之外(无论它是否符合不同的 ISO 标准)。
  • @MT0 没有数据库产品提供的不仅仅是基本的 SQL 标准合规性。这不是免费提供的。 SQL 标准的怪癖非常令人愉快,而且大多数时候都与标准化无关,一切都与供应商将其实施推向其他人有关。时间是 SQL 委员会羞辱 GoT 的一个领域。 ISO8601 不仅仅是“一些其他 ISO 标准”,它是所有语言和服务都支持的日期文字
【解决方案2】:

我只有这些值的数据脚本'2021-08-31T16:30:01.850'

使用TO_TIMESTAMP 将字符串显式转换为TIMESTAMP 数据类型:

INSERT INTO tbl_Account_Master (Account_ID, Verified_Date) 
VALUES (1, TO_TIMESTAMP('2021-08-31T16:30:01.850', 'YYYY-MM-DD"T"HH24:MI:SS.FF3'));

您还可以使用隐式转换(但这不是最佳实践)并更改 Oracle 将隐式用作从字符串转换为 TIMESTAMP 的格式模型的 NLS_TIMESTAMP_FORMAT 会话参数(当没有显式格式模型时)已给出)。

ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS.FF3';

或者,如果您想让小数秒的精度不明确:

ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS.FF';

然后您的 INSERT 查询将起作用(至少直到 NLS_TIMESTAMP_FORMAT 会话参数更改为其他内容,然后您的查询将再次中断......这就是为什么最好不要依赖隐式设置转换格式)。

db小提琴here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2021-11-06
    相关资源
    最近更新 更多