从时间戳列中选择时发生Oracle SQL时间戳错误

2w3rbyxf  于 2023-11-17  发布在  Oracle
关注(0)|答案(4)|浏览(137)

我有一个简单的疑问:

select
timestamp_column
from my_table

字符串
依据:

create table my_table (
timestamp_column timestamp
)

insert into my_table (timestamp_column)
values('11-JUL-23 09.54.22.389941 AM')

insert into my_table (timestamp_column)
values('19-OCT-23 02.27.43.184645 PM')

insert into my_table (timestamp_column)
values('03-OCT-23 11.42.29.618354 AM')

insert into my_table (timestamp_column)
values('22-AUG-23 04.32.15.526578 PM')

insert into my_table (timestamp_column)
values('14-AUG-23 04.07.50.805201 PM')


我在执行select时得到这个错误:

ORA-01830: date format picture ends before converting entire input string


不知道为什么,把它们转换成_char(timestamp_column)作为ABC,它一直在发生。知道为什么吗?

ecr0jaav

ecr0jaav1#

在Oracle中,TIMESTAMP是一种二进制数据类型,由7-13个字节组成,代表世纪、世纪年、月、日、小时、分钟、秒和0到9位小数秒(存储在0-6个字节中)。
当您用途:

insert into my_table (timestamp_column)
values('11-JUL-23 09.54.22.389941 AM')

字符串
您插入的是字符串文字而不是时间戳。
Oracle将尝试提供帮助,并执行从字符串到时间戳的隐式转换,并将您的查询转换为:

insert into my_table (timestamp_column
) values (
  TO_TIMESTAMP(
    '11-JUL-23 09.54.22.389941 AM',
    (SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_TIMESTAMP_FORMAT')
  )
)


如果NLS_TIMESTAMP_FORMAT会话参数与您使用的格式不匹配,则会出现异常。
你应该做的是永远不要依赖隐式类型转换。相反,可以:
1.使用TIMESTAMP文字

INSERT INTO my_table (timestamp_column)
VALUES (TIMESTAMP '2023-07-11 09:54:22.389941')


1.使用TO_TIMESTAMP

INSERT INTO my_table (timestamp_column)
VALUES (
  TO_TIMESTAMP(
    '11-JUL-23 09.54.22.389941 AM',
    'DD-MON-RR HH12.MI.SS.FF6 AM',
    'NLS_DATE_LANGUAGE=English'
  )
)

  • 注意:如果您要使用语言特定的字符串,那么您还应该明确指定日期的语言。

1.不要使用此选项。您可以更改NLS_TIMESTAMP_FORMAT

ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'DD-MON-RR HH12:MI:SS.FF6 AM';


如果日期语言也是正确的,那么您的INSERT将工作,因为隐式转换使用正确的格式模型。但是任何用户都可以随时更改他们的NLS会话参数,所以您不能依赖于此正确。
fiddle

ha5z0ras

ha5z0ras2#

你的select语句很好。问题是你的insert语句,格式不正确。我们不知道是1823还是2023。
使用此格式:

insert into my_table (timestamp_column)
values(TIMESTAMP '2023-10-01 09:54:22');

select *
from my_table;

字符串
输出量:

01-OCT-23 09.54.22.000000

zf2sa74q

zf2sa74q3#

insert into the_table (the_timestamp_column) values (timestamp '2023-10-17 21:22:23');

One can simply use
INSERT INTO MY_TABLE((the_timestamp_column)
 VALUES (TIMESTAMP '2023-10-17 21:22:23.871+02:00');

This way you won't have to worry about date format string, just use default timestamp format.

字符串

ou6hu8tu

ou6hu8tu4#

Oracle对日期格式没有任何假设。有许多不同的方式来表示日期,与其他RDBMS不同的是,它不会试图找出你所指的格式。它必须被告知。如果不是,它将使用默认值,如果它不正确,你会得到一个错误。默认值由nls_date_format参数设置您可以通过查询v$nls_parameters来查看它是什么,或者您可以在会话级别使用alter session set nls_timestamp_format='DD-MON-YY HH.MI.SS.FF AM'自行设置它
但更好的方法是在代码中始终明确日期和时间戳的转换。始终明确提供日期格式模型和明确的TO_CHAR和/或TO_DATE/TO_TIMESTAMP等,就像这样:

insert into my_table (timestamp_column) values (TO_TIMESTAMP('14-AUG-23 04.07.50.805201 PM','DD-MON-YY HH.MI.SS.FF AM'));

字符串

相关问题