ORA-01861: 文字不匹配 char 变量上的格式字符串错误

ORA-01861: literal does not match format string error on char variable

我们刚刚在工作中使用了新计算机,我在 Python 到 cx_Oracle 中 运行 的 SQL 代码停止工作。

当我 运行 代码时 returns ORA-01861 错误说文字与格式字符串不匹配。我读到这通常与日期有关,但在这种情况下,错误消息指的是一个名为 period 的 char 变量。

基本上我的查询是

where period = '2015-02'

表示一年一个月。 period 在数据库中的数据类型是 char。有人在处理 char 变量时识别出这个错误吗?

我应该说,当我 运行 在 SQL 开发人员中使用相同的代码时,它工作得很好。

非常感谢。

嗯,句点是一个 字符串VARCHAR2 数据类型列(或任何其他“CHAR”)?你确定吗?因为,Oracle 错误与 DATE 数据类型有关。

看看下面的例子:

SQL> desc emp
 Name                          Null?    Type
 ----------------------------- -------- --------------------
 EMPNO                         NOT NULL NUMBER(4)
 ENAME                                  VARCHAR2(10)
 JOB                                    VARCHAR2(9)
 MGR                                    NUMBER(4)
 HIREDATE                               DATE           --> HIREDATE is DATE datatype
 SAL                                    NUMBER(7,2)
 COMM                                   NUMBER(7,2)
 DEPTNO                                 NUMBER(2)

我的数据库 return 对于任何 hiredate 是什么?

SQL> select hiredate from emp where rownum = 1;

HIREDATE
--------
17.12.80

啊哈;好的,让我们尝试使用以下日期格式 select 一行(注意 '1980-12-17' 是字符串,而不是日期!):

SQL> select empno, ename, hiredate from emp where hiredate = '1980-12-17';
select empno, ename, hiredate from emp where hiredate = '1980-12-17'
                                                        *
ERROR at line 1:
ORA-01861: literal does not match format string

哦?错误就像你的一样。 你的 日期格式怎么样?

SQL> select empno, ename, hiredate from emp where hiredate = '1980-12';
select empno, ename, hiredate from emp where hiredate = '1980-12'
                                                        *
ERROR at line 1:
ORA-01861: literal does not match format string


SQL>

一样,没有区别。 Oracle 未能 将我提供的字符串隐式“转换”为有效的 DATE 值。那么,怎么办?

最糟糕的是不断提供字符串并希望 Oracle 猜测格式:

SQL> select empno, ename, hiredate from emp where hiredate = '17.12.80';

     EMPNO ENAME      HIREDATE
---------- ---------- --------
      7369 SMITH      17.12.80

SQL>

更好的选择是控制它并提供 DATE 值,例如日期文字(它总是看起来像这样:date 关键字,后跟 yyyy-mm-dd 中的日期格式用单引号括起来):

SQL> select empno, ename, hiredate from emp where hiredate = date '1980-12-17';

     EMPNO ENAME      HIREDATE
---------- ---------- --------
      7369 SMITH      17.12.80

SQL>

这有效。

或者,调整当前会话的 NLS 设置(这是一种 愚蠢的 格式,只是为了表明它无论如何都会工作):

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

Session altered.

SQL> select empno, ename, hiredate from emp where hiredate = '12/1980/17';

     EMPNO ENAME      HIREDATE
---------- ---------- ----------
      7369 SMITH      12/1980/17

SQL>

因此,我建议您 a) 检查 period 列的数据类型, b) 控制处理和比较 日期与日期 ,而不是 日期与字符串 .

P.S。哦,是的 - 为什么 SQL 开发人员“工作”?它的设置识别您提供的格式。

我通过设置解决了

os.environ['NLS_LANG'] = 'swedish'

在我的 cx_Oracle 连接之前。

我要感谢 Littlefoot 帮助我将这个问题归结为 NLS 设置,使我免于错过最后期限。