Oracle 查询失败,添加了 COLLATE 子句
Oracle query fails with added COLLATE clause
在 sqlplus 中,此查询有效:
SQL> SELECT DISTINCT
2 CNTPTY_TYPE
3 FROM visn_exp.V_IHCVSN_CERT_DEP
4 WHERE as_of_dt = '08-may-20'
5 ;
CNTPTY_TYPE
----------------------------------------
Retail
PSE
Non-Financial Corporate
FI
但是这个失败了,整理子句:
SQL> SELECT DISTINCT
2 CNTPTY_TYPE COLLATE latin1_general_CI_AI AS CNTPTY_TYPE
3 FROM VISN_EXP.V_IHCVSN_CERT_DEP
4 WHERE as_of_dt = '08-may-20'
5 ;
CNTPTY_TYPE COLLATE latin_general_CI_AI AS CNTPTY_TYPE
*
ERROR at line 2:
ORA-00923: FROM keyword not found where expected
我应该怎么做才能解决这个问题?
更新:尝试了答案中建议的查询。得到
SQL*另外:12.2.0.1.0 版于 2020 年 5 月 11 日星期一生产 21:03:20
版权所有 (c) 1982、2017,甲骨文。保留所有权利。
输入密码:
上次成功登录时间:2020 年 5 月 11 日星期一 16:51:34 -04:00
连接到:
Oracle Database 12c 企业版 12.1.0.2.0 版 - 64 位生产
随着分区,真正的应用集群,自动存储管理,OLAP,
高级分析和真实应用测试选项
SQL> SELECT DISTINCT
2 CNTPTY_TYPE COLLATE LATIN_AI AS CNTPTY_TYPE
3 FROM VISN_EXP.V_IHCVSN_CERT_DEP
4 WHERE as_of_dt = '08-may-20';
CNTPTY_TYPE COLLATE LATIN_AI AS CNTPTY_TYPE
*
ERROR at line 2:
ORA-00923: FROM keyword not found where expected
使用归类时,有三个后缀会改变排序和比较的行为。
"_CI" : Case insensitive, but accent sensitive.
"_AI" : Both case and accent insensitive.
"_CS" : Both case and accent sensitive. This is default if no extension is used.
虽然不确定上述 _general
用法的目的。但是,仅使用 LATIN_xx
,将 xx 替换为上述任何选项都可以完成您的工作。
检查拉丁语有效 NLS_SORT
值的查询:-
SELECT *
FROM V$NLS_VALID_VALUES
WHERE parameter = 'SORT' and value = 'LATIN';
附加信息:Collations in Oracle
汇总查询:
SELECT DISTINCT
CNTPTY_TYPE COLLATE LATIN_AI AS CNTPTY_TYPE
FROM VISN_EXP.V_IHCVSN_CERT_DEP
WHERE as_of_dt = '08-may-20';
一元运算符COLLATE
是Oracle 12.2才引入的,所以报错是因为你的版本是12.1.
为什么会收到错误消息“FROM
关键字未在预期位置找到”,以及您找到它的确切位置?因为在 Oracle 12.1 中,COLLATE
这个词没有特殊含义。在 SELECT
子句中的列名之后找到它,Oracle 认为它是该列的别名。由于这个别名(无论如何它认为它是一个别名)后面没有逗号用于 select 的附加表达式,它需要关键字 FROM
。它找到了 LATIN_AI
(或者你最初尝试过的任何东西)并且 那是它抛出错误的地方 - 它期待 FROM
在那个地方。
12.1 中的解决方法?有一个,但它有缺点。 COLLATE
的好处是您可以在查询中指定排序规则,而不会影响整个会话。与在查询中调用 TO_DATE
时使用日期格式模型相同,而无需更改 NLS_DATE_FORMAT
.
唉,在 12.1 中,您无法在查询级别控制排序规则;您必须为会话更改它(如果其他查询或您在会话中执行的其他操作需要不同的排序规则,然后将其更改回来)。您可以通过 运行ning
alter session set nls_sort = 'LATIN_AI';
在你运行你的查询之前。
如果在 运行 这个查询之后需要恢复到 "old" nls_sort
,你最好知道它是什么,before 你把它改成 'LATIN_AI'。您可以通过 运行 在 之前 上面显示的 alter session
执行以下查询。
select value from v$nls_parameters where parameter = 'NLS_SORT';
然后,在完成查询后,您需要再次 运行 alter session
以将 nls_sort
更改回旧值。
旁注 - 为什么要将日期与 where
子句中的字符串进行比较? (或者 as_of_date
是字符串数据类型——这是一种更糟糕的做法?)
在 sqlplus 中,此查询有效:
SQL> SELECT DISTINCT
2 CNTPTY_TYPE
3 FROM visn_exp.V_IHCVSN_CERT_DEP
4 WHERE as_of_dt = '08-may-20'
5 ;
CNTPTY_TYPE
----------------------------------------
Retail
PSE
Non-Financial Corporate
FI
但是这个失败了,整理子句:
SQL> SELECT DISTINCT
2 CNTPTY_TYPE COLLATE latin1_general_CI_AI AS CNTPTY_TYPE
3 FROM VISN_EXP.V_IHCVSN_CERT_DEP
4 WHERE as_of_dt = '08-may-20'
5 ;
CNTPTY_TYPE COLLATE latin_general_CI_AI AS CNTPTY_TYPE
*
ERROR at line 2:
ORA-00923: FROM keyword not found where expected
我应该怎么做才能解决这个问题?
更新:尝试了答案中建议的查询。得到
SQL*另外:12.2.0.1.0 版于 2020 年 5 月 11 日星期一生产 21:03:20
版权所有 (c) 1982、2017,甲骨文。保留所有权利。
输入密码: 上次成功登录时间:2020 年 5 月 11 日星期一 16:51:34 -04:00
连接到: Oracle Database 12c 企业版 12.1.0.2.0 版 - 64 位生产 随着分区,真正的应用集群,自动存储管理,OLAP, 高级分析和真实应用测试选项
SQL> SELECT DISTINCT
2 CNTPTY_TYPE COLLATE LATIN_AI AS CNTPTY_TYPE
3 FROM VISN_EXP.V_IHCVSN_CERT_DEP
4 WHERE as_of_dt = '08-may-20';
CNTPTY_TYPE COLLATE LATIN_AI AS CNTPTY_TYPE
*
ERROR at line 2:
ORA-00923: FROM keyword not found where expected
使用归类时,有三个后缀会改变排序和比较的行为。
"_CI" : Case insensitive, but accent sensitive.
"_AI" : Both case and accent insensitive.
"_CS" : Both case and accent sensitive. This is default if no extension is used.
虽然不确定上述 _general
用法的目的。但是,仅使用 LATIN_xx
,将 xx 替换为上述任何选项都可以完成您的工作。
检查拉丁语有效 NLS_SORT
值的查询:-
SELECT *
FROM V$NLS_VALID_VALUES
WHERE parameter = 'SORT' and value = 'LATIN';
附加信息:Collations in Oracle
汇总查询:
SELECT DISTINCT
CNTPTY_TYPE COLLATE LATIN_AI AS CNTPTY_TYPE
FROM VISN_EXP.V_IHCVSN_CERT_DEP
WHERE as_of_dt = '08-may-20';
一元运算符COLLATE
是Oracle 12.2才引入的,所以报错是因为你的版本是12.1.
为什么会收到错误消息“FROM
关键字未在预期位置找到”,以及您找到它的确切位置?因为在 Oracle 12.1 中,COLLATE
这个词没有特殊含义。在 SELECT
子句中的列名之后找到它,Oracle 认为它是该列的别名。由于这个别名(无论如何它认为它是一个别名)后面没有逗号用于 select 的附加表达式,它需要关键字 FROM
。它找到了 LATIN_AI
(或者你最初尝试过的任何东西)并且 那是它抛出错误的地方 - 它期待 FROM
在那个地方。
12.1 中的解决方法?有一个,但它有缺点。 COLLATE
的好处是您可以在查询中指定排序规则,而不会影响整个会话。与在查询中调用 TO_DATE
时使用日期格式模型相同,而无需更改 NLS_DATE_FORMAT
.
唉,在 12.1 中,您无法在查询级别控制排序规则;您必须为会话更改它(如果其他查询或您在会话中执行的其他操作需要不同的排序规则,然后将其更改回来)。您可以通过 运行ning
alter session set nls_sort = 'LATIN_AI';
在你运行你的查询之前。
如果在 运行 这个查询之后需要恢复到 "old" nls_sort
,你最好知道它是什么,before 你把它改成 'LATIN_AI'。您可以通过 运行 在 之前 上面显示的 alter session
执行以下查询。
select value from v$nls_parameters where parameter = 'NLS_SORT';
然后,在完成查询后,您需要再次 运行 alter session
以将 nls_sort
更改回旧值。
旁注 - 为什么要将日期与 where
子句中的字符串进行比较? (或者 as_of_date
是字符串数据类型——这是一种更糟糕的做法?)