Trabalhando com palavras reservadas no Banco de Dados Oracle
INTRODUÇÃO
Palavras reservadas em banco de dados são palavras chaves utilizadas em definições de sintaxe. Uma palavra chave pode ser sempre reservada ou somente em casos específicos.
O Oracle possui uma view chamada v$reserved_words, onde é possível a visualização das palavras que são tidas como reservadas. Cada palavra é reservada de acordo com uma definição específica, sendo elas apresentadas nos cenários a seguir:
Figura 1 – V$reserved_words
- Cenário 1 : Palavra chave utilizada como Identificador : Palavras chaves utilizadas como identificadores apresentam valor igual à ‘Y’ de Yes na coluna RESERVED (Primeiro R na sequência de coluna da view). Segue abaixo um exemplo de um erro sendo reportado durante a criação de usuário, utilizando a palavra reservada minus.
SQL> create user MINUS identified by MINUS;
create user MINUS identified by 'MINUS'
*
ERROR at line 1:
ORA-01935: missing user or role name
— Com isso, segue uma consulta na view com o intuito de se verificar se há alguma palavra reservada no Oracle que contenha a string ‘MIN’ e que seja reconhecida como uma palavra reservada de identificador.
SQL> select * from v$reserved_words where reserved='Y' and keyword like '%MIN%';
KEYWORD LENGTH R R R R D
------------------------------ ---------- - - - - -
MINUS 5 Y N N N N
— No entanto, há como forçar a criação do usuário, mesmo que a palavra seja uma palavra reservada. Todavia, ressalta-se que não é uma boa prática.
SQL> CREATE USER "MINUS" IDENTIFIED BY "MINUS";
User created.
- Cenário 2 : Palavra chave utilizada como Tipo do nome e palavra chave utilizada como identificador em situações específicas: Palavras chaves utilizadas como tipos de nomes apresentam valor igual à ‘Y’ de Yes na coluna RES_TYPE (Segundo R na sequência de coluna da view), enquanto que palavras chaves utilizadas como identificadores em situações específicas, apresentam valor igual à ‘Y’ de Yes na coluna RES_SEMI (Quarto R na sequência de coluna da view). Segue um exemplo abaixo de erro reportado durante a criação de um tipo:
SQL> CREATE TYPE audit AS TABLE OF VARCHAR2(10)
/
CREATE TYPE empregados AS object (
cod INTEGER(4),
nome VARCHAR2(25),
courses audit )
/ 2 CREATE TYPE audit AS TABLE OF VARCHAR2(10)
*
ERROR at line 1:
ORA-02302: invalid or missing type name
— Sendo assim, segue uma consulta na view com o intuito de se verificar se há alguma palavra reservada no Oracle que contenha a string ‘AUD’ e que seja reconhecida como uma palavra reservada. Note o valor igual à ‘Y’ para o quarto R da view, representando uma palavra reservada de identificador em situações específicas :
SQL> SELECT * FROM v$reserved_words where KEYWORD LIKE '%AUD%';
KEYWORD LENGTH R R R R D
------------------------------ ---------- - - - - -
AUDIT 5 N N N Y N
NOAUDIT 7 N N N Y N
-- Utilizamos o mesmo PL/SQL acima, apenas trocando o tipo do nome definido como Audit para Auditoria_banco e, com isso, o erro não mais persistiu. Uma vez que, a segunda opção não é uma palavra reservada do Oracle, ao contrário da primeira:
SQL> CREATE TYPE auditoria_banco AS TABLE OF VARCHAR2(10)
/
CREATE TYPE empregados AS object (
cod INTEGER(4),
nome VARCHAR2(25),
courses auditoria_banco )
/ 2
Type created.
SQL> 2 3 4 5
Type created.
- Cenário 3 : Palavra chave utilizada como nome de atributo e palavra chave como duplicata de outra palavra chave: Palavras chaves utilizadas como nomes de atributos apresentam valor igual à ‘Y’ de Yes na coluna RES_ATTR (Terceira R na sequência de coluna da view). Um atributo é um dado associado para cada especificação de uma entidade ou em alguns casos, relacionamentos. No entanto, palavra chave utilizada como duplicata de outra palavra chave, apresentam valor igual à ‘Y’ de Yes na coluna DUPLICATE. No entanto, palavras reservadas como duplicata de outra palavras, não são apenas as definidas como ‘Y’ na view v$reserved_words e, sim, também as palavras já existentes, como por exemplo, em nomes de objetos.
Segue abaixo a representação de um objeto que já possui um determinado nome, e o usuário tenta criar outro objeto com este nome já existente.
SQL> CREATE TABLE tb(
ID_rg varchar(15) primary key,
Nome varchar(15)
); 2 3 4
Table created.
SQL> create table bruno.tb_jogadores as select * from tb;
Table created.
SQL> create public synonym tb_jogadores for Laura.tb_jogadores;
Synonym created.
SQL> create public synonym tb_jogadores for bruno.tb_jogadores
2 ;
create public synonym tb_jogadores for bruno.tb_jogadores
*
ERROR at line 1:
ORA-00955: name is already used by an existing object
— A Oracle fornece um HELP das palavras reservadas do banco de dados. Para acessá-lo, basta digitar a sintaxe ‘Help Reserved Words’. Segue exemplo abaixo.
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*
CONCLUSÃO
A view v$reserved_words é uma ótima view que possibilita ao administrador de banco de dados um conhecimento do contexto das palavras que são definidas como reservadas na base de dados e, com isso, evitando equívocos em sintaxes para criação de um determinado objeto, usuário ou qualquer comando PL/SQL, quando utilizado na base de dados.
REFERÊNCIAS
- Create Type
- PL/SQL Collections and Records
- Oracle SQL Reserved Words
- V$RESERVED_WORDS
- Oracle Database Reserved Words
- V$RESERVED_WORDS
- Oracle Reserved Words, Keywords, and Namespaces