sql - 如何处理通过 shell 脚本执行的 Oracle SQL 选择语句中的保留字?
问题描述
在 Oracle 中有一个带有保留字的表。下面是我通过将 Double 引用到保留字来执行的查询。但得到错误
sqlplus -s user/'pwd'@schema @sql_file.sql 4 "nvl(to_char(\"sys_updated_on\",'YYYY-MM-DD HH24:MI:SS'),'2020-01-01 00:00:00')" SCHEMA.TABLE
ERROR:
ORA-01740: missing double quote in identifier
没有双引号低于错误。
ERROR at line 1:
ORA-00904: "SYS_UPDATED_ON": invalid identifier
我尝试了多种选择来转义保留字。任何帮助将不胜感激!
SQL 文件的内容
select /*+ parallel (m, &1) */ max(least(&2)) from &3 m;
解决方案
问题是您使用带引号的标识符创建对象。
从文档中:
带引号的标识符以双引号 (") 开头和结尾。如果您使用带引号的标识符命名架构对象,则在引用该对象时必须使用双引号。
如果您使用带引号的标识符创建对象,则它会区分大小写。
演示:
让我们使用带引号的标识符创建一个大写的列:
CREATE TABLE t_test (
"SYS_UPDATED_ON" NUMBER
);
SELECT "sys_updated_on" FROM t_test;
ORA-00904: "sys_updated_on": invalid identifier
即使您DESCRIBE表格,您也不会看到双引号:
DESC t_test;
Name Null? Type
-------------- ----- ------
SYS_UPDATED_ON NUMBER
它应该被称为:
SELECT "SYS_UPDATED_ON" FROM t_test;
现在,让我们使用带引号的标识符创建一个小写的列:
CREATE TABLE t_test_1 (
"sys_updated_on" NUMBER
);
SELECT SYS_UPDATED_ON FROM t_test_1;
SQL Error: ORA-00904: "SYS_UPDATED_ON": invalid identifier
描述表格会让您知道对象名称是否区分大小写:
DESC t_test_1;
Name Null? Type
-------------- ----- ------
sys_updated_on NUMBER
正确的方法是使用双引号创建的名称:
SELECT "sys_updated_on" FROM t_test_1;
关于SQL 和 PL/SQL 中的RESERVED字,您可以使用SQL*Plus 帮助实用程序列出所有这些字:
Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0
SQL> help reserved words;
RESERVED WORDS (PL/SQL)
-----------------------
PL/SQL Reserved Words have special meaning in PL/SQL, and may not be used
for identifier names (unless enclosed in "quotes").
An asterisk (*) indicates words are also SQL Reserved Words.
ALL* DESC* JAVA PACKAGE SUBTYPE
ALTER* DISTINCT* LEVEL* PARTITION SUCCESSFUL*
AND* DO LIKE* PCTFREE* SUM
ANY* DROP* LIMITED PLS_INTEGER SYNONYM*
ARRAY ELSE* LOCK* POSITIVE SYSDATE*
AS* ELSIF LONG* POSITIVEN TABLE*
ASC* END LOOP PRAGMA THEN*
AT EXCEPTION MAX PRIOR* TIME
AUTHID EXCLUSIVE* MIN PRIVATE TIMESTAMP
AVG EXECUTE MINUS* PROCEDURE TIMEZONE_ABBR
BEGIN EXISTS* MINUTE PUBLIC* TIMEZONE_HOUR
BETWEEN* EXIT MLSLABEL* RAISE TIMEZONE_MINUTE
BINARY_INTEGER EXTENDS MOD RANGE TIMEZONE_REGION
BODY EXTRACT MODE* RAW* TO*
BOOLEAN FALSE MONTH REAL TRIGGER*
BULK FETCH NATURAL RECORD TRUE
BY* FLOAT* NATURALN REF TYPE
CHAR* FOR* NEW RELEASE UI
CHAR_BASE FORALL NEXTVAL RETURN UNION*
CHECK* FROM* NOCOPY REVERSE UNIQUE*
CLOSE FUNCTION NOT* ROLLBACK UPDATE*
CLUSTER* GOTO NOWAIT* ROW* USE
COALESCE GROUP* NULL* ROWID* USER*
COLLECT HAVING* NULLIF ROWNUM* VALIDATE*
COMMENT* HEAP NUMBER* ROWTYPE VALUES*
COMMIT HOUR NUMBER_BASE SAVEPOINT VARCHAR*
COMPRESS* IF OCIROWID SECOND VARCHAR2*
CONNECT* IMMEDIATE* OF* SELECT* VARIANCE
CONSTANT IN* ON* SEPERATE VIEW*
CREATE* INDEX* OPAQUE SET* WHEN
CURRENT* INDICATOR OPEN SHARE* WHENEVER*
CURRVAL INSERT* OPERATOR SMALLINT* WHERE*
CURSOR INTEGER* OPTION* SPACE WHILE
DATE* INTERFACE OR* SQL WITH*
DAY INTERSECT* ORDER* SQLCODE WORK
DECIMAL* INTERVAL ORGANIZATION SQLERRM WRITE
DECLARE INTO* OTHERS START* YEAR
DEFAULT* IS* OUT STDDEV ZONE
DELETE* ISOLATION
RESERVED WORDS (SQL)
--------------------
SQL Reserved Words have special meaning in SQL, and may not be used for
identifier names unless enclosed in "quotes".
An asterisk (*) indicates words are also ANSI Reserved Words.
Oracle prefixes implicitly generated schema object and subobject names
with "SYS_". To avoid name resolution conflict, Oracle discourages you
from prefixing your schema object and subobject names with "SYS_".
ACCESS DEFAULT* INTEGER* ONLINE START
ADD* DELETE* INTERSECT* OPTION* SUCCESSFUL
ALL* DESC* INTO* OR* SYNONYM
ALTER* DISTINCT* IS* ORDER* SYSDATE
AND* DROP* LEVEL* PCTFREE TABLE*
ANY* ELSE* LIKE* PRIOR* THEN*
AS* EXCLUSIVE LOCK PRIVILEGES* TO*
ASC* EXISTS LONG PUBLIC* TRIGGER
AUDIT FILE MAXEXTENTS RAW UID
BETWEEN* FLOAT* MINUS RENAME UNION*
BY* FOR* MLSLABEL RESOURCE UNIQUE*
CHAR* FROM* MODE REVOKE* UPDATE*
CHECK* GRANT* MODIFY ROW USER*
CLUSTER GROUP* NOAUDIT ROWID VALIDATE
COLUMN HAVING* NOCOMPRESS ROWNUM VALUES*
COMMENT IDENTIFIED NOT* ROWS* VARCHAR*
COMPRESS IMMEDIATE* NOWAIT SELECT* VARCHAR2
CONNECT* IN* NULL* SESSION* VIEW*
CREATE* INCREMENT NUMBER SET* WHENEVER*
CURRENT* INDEX OF* SHARE WHERE
DATE* INITIAL OFFLINE SIZE* WITH*
DECIMAL* INSERT* ON* SMALLINT*
推荐阅读
- python - 多天的时间段
- jupyter-notebook - 将图形渲染为树
- c++ - 在 C++ 中打开文本文件的输入验证
- logstash - 阅读文档后如何自动停止logstash流程实例
- amazon-web-services - AWS API Gateway VPC 链接定价
- node.js - npm install 将某些包的包锁定从 registry.npmjs.org 更改为 registry.yarnpkg.com
- excel - 如何使用包含方括号数组的 excel 单元格中的值初始化 VBA 中的数组?
- python - python pandas函数对象没有属性min
- selenium - Selenium IDE Version 3.17.0 如何捕捉新窗口句柄
- javascript - 当用户空闲 10 秒时单击按钮的 Javascript 函数