SQL TO_DATE-针对每个日期字段?

SQL TO_DATE-针对每个日期字段?,sql,oracle,insert,to-date,Sql,Oracle,Insert,To Date,在使用MySQL多年之后,不得不将表移到Oracle SQL(我使用的是SQL Developer)。创建了表,现在只想用一条INSERT语句检查它,得到以下结果: INSERT INTO table_name VALUES ('1001','LAWRENCE-INDIANAPOLIS','01-06-02','I8112NP','05DX8105408','2013-06-03','2016-03-11','2018-04-29','2038-01-01','yes','yes','yes'

在使用MySQL多年之后,不得不将表移到Oracle SQL(我使用的是SQL Developer)。创建了表,现在只想用一条INSERT语句检查它,得到以下结果:

INSERT INTO table_name 
VALUES ('1001','LAWRENCE-INDIANAPOLIS','01-06-02','I8112NP','05DX8105408','2013-06-03','2016-03-11','2018-04-29','2038-01-01','yes','yes','yes','2012-10-25','CCE','7360D33','R8NR6N0','70F63951959F9','2016-03-11')

Error report -
SQL Error: ORA-01861: literal does not match format string
01861. 00000 -  "literal does not match format string"
*Cause:    Literals in the input must be the same length as literals in
           the format string (with the exception of leading whitespace).      
If the "FX" modifier has been toggled on, the literal must match exactly,
       with no extra whitespace.
*Action:   Correct the format string to match the literal.

我真的必须在INSERT语句中的每个日期字段前面放置一个“截止日期”格式,即使它们已经是正确的YYYY-MM-DD格式吗?

在Oracle中,使用
日期关键字:

INSERT INTO table_name 
    VALUES ('1001', 'LAWRENCE-INDIANAPOLIS', '01-06-02', 'I8112NP', '05DX8105408',
            DATE '2013-06-03', DATE '2016-03-11', DATE '2018-04-29', DATE '2038-01-01', 'yes', 'yes', 'yes', DATE '2012-10-25', 'CCE', '7360D33', 'R8NR6N0', '70F63951959F9', DATE '2016-03-11'
           );

在Oracle中,使用
date
关键字:

INSERT INTO table_name 
    VALUES ('1001', 'LAWRENCE-INDIANAPOLIS', '01-06-02', 'I8112NP', '05DX8105408',
            DATE '2013-06-03', DATE '2016-03-11', DATE '2018-04-29', DATE '2038-01-01', 'yes', 'yes', 'yes', DATE '2012-10-25', 'CCE', '7360D33', 'R8NR6N0', '70F63951959F9', DATE '2016-03-11'
           );

好吧,你不必每次都这么做,但良好的实践表明,你应该指导Oracle你拥有什么以及你期望它做什么

它是关于NLS设置的。如果日期格式与您使用的格式不同,您将得到一个错误(您已经知道):

但是,如果您修改日期格式,使其与您使用的格式匹配,则一切正常:

SQL> alter session set nls_date_format = 'yyyy-mm-dd';

Session altered.

SQL> insert into test values ('2013-06-03');

1 row created.

SQL>
另一个不依赖NLS设置的选项是使用日期文字。其格式始终为YYYY-MM-DD,且必须在日期关键字之前:

SQL> alter session set nls_date_format = 'dd.mm.yyyy';

Session altered.

SQL> insert into test values ('2013-06-03');
insert into test values ('2013-06-03')
                         *
ERROR at line 1:
ORA-01861: literal does not match format string


SQL> insert into test values (date '2013-06-03');

1 row created.

SQL>

或者,正如您所发现的,使用带有适当格式掩码的
来更新函数。

好吧,您不必每次都这样做,但良好的实践表明,您应该指导Oracle您拥有什么以及您期望它做什么

它是关于NLS设置的。如果日期格式与您使用的格式不同,您将得到一个错误(您已经知道):

但是,如果您修改日期格式,使其与您使用的格式匹配,则一切正常:

SQL> alter session set nls_date_format = 'yyyy-mm-dd';

Session altered.

SQL> insert into test values ('2013-06-03');

1 row created.

SQL>
另一个不依赖NLS设置的选项是使用日期文字。其格式始终为YYYY-MM-DD,且必须在日期关键字之前:

SQL> alter session set nls_date_format = 'dd.mm.yyyy';

Session altered.

SQL> insert into test values ('2013-06-03');
insert into test values ('2013-06-03')
                         *
ERROR at line 1:
ORA-01861: literal does not match format string


SQL> insert into test values (date '2013-06-03');

1 row created.

SQL>

或者,如您所知,使用带有适当格式掩码的
TO_DATE
函数。

使用的默认日期格式取决于NLS_DATE_format环境变量的设置。要了解这是什么,请使用以下查询:

SELECT *
  FROM V$NLS_PARAMETERS
  ORDER BY PARAMETER;
这将转储当前在数据库中设置的所有NLS参数。例如,在我现在使用的数据库中,上面的查询返回:

NLS_CALENDAR               GREGORIAN
NLS_CHARACTERSET           US7ASCII
NLS_COMP                   BINARY
NLS_CURRENCY               $
NLS_DATE_FORMAT            DD-MON-RR
NLS_DATE_LANGUAGE          AMERICAN
NLS_DUAL_CURRENCY          $
NLS_ISO_CURRENCY           AMERICA
NLS_LANGUAGE               AMERICAN
NLS_LENGTH_SEMANTICS       BYTE
NLS_NCHAR_CHARACTERSET     AL16UTF16
NLS_NCHAR_CONV_EXCP        FALSE
NLS_NUMERIC_CHARACTERS     .,
NLS_SORT                   BINARY
NLS_TERRITORY              AMERICA
NLS_TIMESTAMP_FORMAT       DD-MON-RR HH.MI.SSXFF AM
NLS_TIMESTAMP_TZ_FORMAT    DD-MON-RR HH.MI.SSXFF AM TZR
NLS_TIME_FORMAT            HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT         HH.MI.SSXFF AM TZR

因此,在我的系统上,如果我想以字符串形式输入日期并让Oracle正确翻译,我必须输入is,例如2018年4月24日。

使用的默认日期格式取决于NLS_date_format环境变量的设置。要了解这是什么,请使用以下查询:

SELECT *
  FROM V$NLS_PARAMETERS
  ORDER BY PARAMETER;
这将转储当前在数据库中设置的所有NLS参数。例如,在我现在使用的数据库中,上面的查询返回:

NLS_CALENDAR               GREGORIAN
NLS_CHARACTERSET           US7ASCII
NLS_COMP                   BINARY
NLS_CURRENCY               $
NLS_DATE_FORMAT            DD-MON-RR
NLS_DATE_LANGUAGE          AMERICAN
NLS_DUAL_CURRENCY          $
NLS_ISO_CURRENCY           AMERICA
NLS_LANGUAGE               AMERICAN
NLS_LENGTH_SEMANTICS       BYTE
NLS_NCHAR_CHARACTERSET     AL16UTF16
NLS_NCHAR_CONV_EXCP        FALSE
NLS_NUMERIC_CHARACTERS     .,
NLS_SORT                   BINARY
NLS_TERRITORY              AMERICA
NLS_TIMESTAMP_FORMAT       DD-MON-RR HH.MI.SSXFF AM
NLS_TIMESTAMP_TZ_FORMAT    DD-MON-RR HH.MI.SSXFF AM TZR
NLS_TIME_FORMAT            HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT         HH.MI.SSXFF AM TZR

所以在我的系统中,如果我想输入一个字符串形式的日期并让Oracle正确翻译,我就必须输入,例如2018年4月24日。

是的,如果这些列的数据类型是
date
或使用
date'2013-06-03'
…我的错-只是刚从同事那里得知Oracle日期格式与MySQL日期不一样总体安排在放入INSERT语句之前,解析从MySQL表中选择的数据并将其格式化为Oracle SQL可能会更容易。如果您正确定义了表,这意味着日期列位于
date
数据类型中,那么您很幸运:您可以更改
NLS\u date\u格式设置。但我发现了一个问题:在您尝试的代码中,日期有两种格式。。。“01-06-02”到底是什么意思?哪一年是哪一个月?您需要所有“传入”列使用相同的格式,例如
'2013-06-03'
;否则,您将只需要在非“标准化”格式的列上使用
to_date
。还有一个问题。。。你不能直接将日期迁移到Oracle
date
数据类型吗?是的,如果这些列的数据类型是
date
或使用
date'2013-06-03'
…我的错-只是刚从同事那里得知Oracle日期格式与MySQL日期格式不同。在放入INSERT语句之前,解析从MySQL表中选择的数据并将其格式化为Oracle SQL可能会更容易。如果您正确定义了表,这意味着日期列位于
date
数据类型中,那么您很幸运:您可以更改
NLS\u date\u格式设置。但我发现了一个问题:在您尝试的代码中,日期有两种格式。。。“01-06-02”到底是什么意思?哪一年是哪一个月?您需要所有“传入”列使用相同的格式,例如
'2013-06-03'
;否则,您将只需要在非“标准化”格式的列上使用
to_date
。还有一个问题。。。您不能直接将从其他RDBMS迁移的现有数据上的日期迁移到Oracle
date
数据类型吗?我不这么认为。在现有数据上,从另一个RDBMS迁移哪些数据?我不这么认为。Date literal-用于从现有表复制数据(从另一个RDBMS迁移到Oracle)?我不这么认为。那些值(发布的OP)已经是YYYY-MM-DD格式,用单引号括起来,缺少的只是日期(关键字)字。我不知道,从来没有从MySQL迁移过任何东西,但这看起来并不是什么大问题(添加日期)。不过,我可能错了。如果有数百万甚至数千人要迁移的行数可能会很烦人。我认为NLS设置选项可能是更好的选项。“烦人”不是问题所在。如果列中已经存在日期(可能是字符串数据类型),则不能简单地将关键字
DATE
添加到它们前面。这甚至不是MySQL的问题,它也是Oracle的内部问题。
DATE
literal只接受字符串文本,您不能写入
DATE col1
,其中col1是格式为“yyyy-mm-dd”的varchar2列,即在Oracle.DATE literal中使用
DATE
关键字无效,无法从现有表复制数据(从另一个RDBMS迁移到Oracl)