Как обработать зарезервированные слова в Oracle SQL операторе выбора, выполняемом через скрипт оболочки? - PullRequest
2 голосов
/ 14 апреля 2020

Иметь таблицу с зарезервированным словом в Oracle. Ниже приведен запрос, который я выполняю, заключив в двойную кавычку зарезервированное слово. Но получая ОШИБКУ

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;

Ответы [ 2 ]

0 голосов
/ 15 апреля 2020

В Windows вам нужно будет использовать четыре двойные кавычки - одну для экранирования интерпретатора командной строки и одну для экранирования SQL* Плюс интерпретации аргумента.

C:\>sqlplus -s user/password@orcl @sql_file.sql 4 "nvl(to_char(""""sys_updated_on"""",'YYYY-MM-DD HH24:MI:SS'),'2020-01-01 00:00:00')" foo
old   1: select /*+ parallel (m, &1) */ max(least(&2)) from &3 m
new   1: select /*+ parallel (m, 4) */ max(least(nvl(to_char("sys_updated_on",'YYYY-MM-DD HH24:MI:SS'),'2020-01-01 00:00:00'))) from foo m

MAX(LEAST(NVL(TO_CHAR("SYS_UPDATED_ON",'YYYY-MM-DDHH24:MI
---------------------------------------------------------
2000-01-01 00:00:00

Я использовал этот пример схемы:

create table foo("sys_updated_on" date);
insert into foo values(date '2000-01-01');
commit;

Я согласен с Lalit, что было бы легче избежать использования указанных в кавычках идентификаторов. Но я понимаю, что мы не всегда выбираем наши схемы.

0 голосов
/ 14 апреля 2020

Проблема в том, что вы использовали создание объекта с использованием цитируемого идентификатора .

Из документации :

Цитата Идентификатор начинается и заканчивается двойными кавычками ("). Если вы называете объект схемы с помощью заключенного в кавычки идентификатора, то вы должны использовать двойные кавычки, когда ссылаетесь на этот объект.

Если вы создаете объект, использующий идентификаторы в кавычках, становится чувствительным к регистру .

Демо:

Давайте создадим столбец в верхний регистр используя указанный в кавычках идентификатор:

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 

Это должно быть указано as:

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;

Относительно RESERVED слов в SQL и PL / SQL, вы можете использовать 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* 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...