Oracle查询在添加COLLATE子句时失败

问题描述 投票:0回答:1

在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*Plus。版本12.2.0.1.0 生产版于Mon May 11 21:03:20 2020。

Copyright (c) 1982, 2017, Oracle. 保留所有权利。

输入密码:上次成功登录时间。Mon May 11 2020 16:51:34 -04:00

连接到:Oracle数据库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
oracle sqlplus collation
1个回答
3
投票

单元运算符 COLLATE 是在Oracle 12.2中才引入的,所以你得到的错误是因为你的版本是12.1。

为什么你会得到错误的"FROM 关键词在预期的地方没有找到",到底在哪里找到的呢?因为在Oracle 12.1中,这个词 COLLATE 没有特殊的含义。在 SELECT 子句,Oracle认为它是列的别名。而由于这个别名(反正它认为是别名)后面并没有跟上逗号来选择额外的表达式,所以它期望用关键字 FROM. 它发现 LATIN_AI 取而代之(或你最初尝试的任何东西),并且 那是 抛出错误的地方--它期望的是 FROM 正是在那个地方。

12.1中的变通方法?有一个,但它有缺点。的好处是 COLLATE 是你可以在查询中表示整理,而不影响你的整体会话。和使用日期格式模型一样,当你调用 TO_DATE 中,而无需更改 NLS_DATE_FORMAT.

唉,在12.1中,你不能控制查询级别的整理;你必须为会话改变它(如果你在会话中做的其他查询或其他事情需要一个不同的整理,那么就把它改回来)。你可以通过运行

alter session set nls_sort = 'LATIN_AI';

在你运行查询之前。

如果你需要恢复到 "旧的" nls_sort 当你运行这个查询后,你最好知道它是什么。之前 你把它改为'LATIN_AI'。你可以通过运行以下查询来实现 之前alter session 如上图所示。

select value from v$nls_parameters where parameter = 'NLS_SORT';

然后,当你完成查询后,你需要执行 alter session 再改 nls_sort 返回到旧值。

侧面说明--为什么你要在 where 条款?(或者是 as_of_date 在字符串数据类型中--这是更糟糕的做法?)


0
投票

当使用整理时,有三个后缀会改变排序和比较的行为。

"_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'; 

附加信息 : 甲骨文中的整理

总结查询 :

SELECT DISTINCT
CNTPTY_TYPE COLLATE LATIN_AI AS CNTPTY_TYPE
FROM VISN_EXP.V_IHCVSN_CERT_DEP
WHERE as_of_dt = '08-may-20';
© www.soinside.com 2019 - 2024. All rights reserved.