Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

ORA-00907:parêntese direito ausente


ORA-00907:parêntese direito ausente

Esta é uma das várias mensagens de erro genéricas que indicam que nosso código contém um ou mais erros de sintaxe. Às vezes pode significar que literalmente omitimos um colchete direito; é fácil verificar se estamos usando um editor que tem um colchete de correspondência capacidade (a maioria dos editores de texto destinados a codificadores faz). Mas muitas vezes isso significa que o compilador encontrou uma palavra-chave fora de contexto. Ou talvez seja uma palavra incorreta, um espaço em vez de um sublinhado ou uma vírgula ausente.

Infelizmente, as possíveis razões pelas quais nosso código não compila são virtualmente infinitas e o compilador simplesmente não é inteligente o suficiente para distingui-las. Então ele lança uma mensagem genérica, um pouco enigmática, como ORA-00907: missing right parenthesis e deixa para nós a localização do bloomer real.

O script postado tem vários erros de sintaxe. Primeiro, discutirei o erro que aciona o ORA-0097, mas você precisará corrigi-los todos.

As restrições de chave estrangeira podem ser declaradas de acordo com a coluna de referência ou no nível da tabela após a declaração de todas as colunas. Estes têm sintaxes diferentes; seus scripts misturam os dois e é por isso que você obtém o ORA-00907.

A declaração em linha não tem vírgula e não inclui o nome da coluna de referência.
CREATE TABLE historys_T    (
    history_record    VARCHAR2 (8),
    customer_id       VARCHAR2 (8) 
          CONSTRAINT historys_T_FK FOREIGN KEY REFERENCES T_customers ON DELETE CASCADE,
    order_id           VARCHAR2 (10) NOT NULL,
          CONSTRAINT fk_order_id_orders REFERENCES orders ON DELETE CASCADE)

As restrições de nível de tabela são um componente separado e, portanto, têm uma vírgula e mencionam a coluna de referência.
CREATE TABLE historys_T    (
    history_record    VARCHAR2 (8),
    customer_id       VARCHAR2 (8),    
    order_id           VARCHAR2 (10) NOT NULL,
    CONSTRAINT historys_T_FK FOREIGN KEY (customer_id) REFERENCES T_customers ON DELETE CASCADE,   
   CONSTRAINT fk_order_id_orders FOREIGN KEY (order_id) REFERENCES orders ON DELETE CASCADE)

Aqui está uma lista de outros erros de sintaxe:
  1. A tabela referenciada (e a chave primária ou restrição exclusiva referenciada) já deve existir antes que possamos criar uma chave estrangeira para ela. Portanto, você não pode criar uma chave estrangeira para HISTORYS_T antes de criar os ORDERS referenciados tabela.
  2. Você digitou incorretamente os nomes das tabelas referenciadas em algumas das cláusulas de chave estrangeira (LIBRARY_T e FORMAT_T ).
  3. Você precisa fornecer uma expressão na cláusula DEFAULT. Para colunas DATE que geralmente é a data atual, DATE DEFAULT sysdate .

Olhar para o nosso próprio código com um olhar frio é uma habilidade que todos nós precisamos adquirir para ter sucesso como desenvolvedores. Ajuda muito estar familiarizado com a documentação da Oracle. Uma comparação lado a lado de seu código e os exemplos na Referência SQL teria ajudado a resolver esses erros de sintaxe em consideravelmente menos de dois dias. Encontre aqui (11g) e aqui (12c).

Além de erros de sintaxe, seus scripts contêm erros de design. Não são fracassos, mas más práticas que não devem se tornar hábitos.
  1. Você não nomeou a maioria de suas restrições. A Oracle dará a eles um nome padrão, mas será horrível, e tornará o dicionário de dados mais difícil de entender. Nomear explicitamente cada restrição nos ajuda a navegar no banco de dados físico. Isso também leva a mensagens de erro mais compreensíveis quando nosso SQL aciona uma violação de restrição.
  2. Nomeie suas restrições de forma consistente. HISTORY_T tem restrições chamadas historys_T_FK e fk_order_id_orders , nenhum dos quais é útil. Uma convenção útil é <child_table>_<parent_table>_fk . Então history_customer_fk e history_order_fk respectivamente.
  3. Pode ser útil criar as restrições com instruções separadas. Criar tabelas e depois chaves primárias e chaves estrangeiras evitará os problemas com a ordenação de dependência identificados acima.
  4. Você está tentando criar chaves estrangeiras cíclicas entre LIBRARY_T e FORMATS . Você pode fazer isso criando as restrições em uma instrução separada, mas não:você terá problemas ao inserir linhas e problemas ainda piores com exclusões. Você deve reconsiderar seu modelo de dados e encontrar uma maneira de modelar o relacionamento entre as duas tabelas para que uma seja o pai e a outra o filho. Ou talvez você precise de um tipo diferente de relacionamento, como uma tabela de interseção.
  5. Evite linhas em branco em seus scripts. Algumas ferramentas irão lidar com eles, mas outras não. Podemos configurar o SQL*Plus para lidar com eles, mas é melhor evitar a necessidade.
  6. A convenção de nomenclatura de LIBRARY_T é feio. Tente encontrar um nome mais expressivo que não exija um sufixo desnecessário para evitar um conflito de palavras-chave.
  7. T_CUSTOMERS é ainda mais feio, sendo inconsistente com suas outras tabelas e completamente desnecessário, pois customers não é uma palavra-chave.

Dar nome às coisas é difícil. Você não acreditaria nas discussões que tive sobre os nomes das mesas ao longo dos anos. O mais importante é a consistência. Se eu olhar para um dicionário de dados e ver tabelas chamadas T_CUSTOMERS e LIBRARY_T minha primeira resposta seria confusão. Por que essas tabelas são nomeadas com convenções diferentes? Que diferença conceitual isso expressa? Então, por favor, decida sobre uma convenção de nomenclatura e cumpra. Faça com que seus nomes de tabela sejam todos singulares ou todos plurais. Evite prefixos e sufixos tanto quanto possível; já sabemos que é uma tabela, não precisamos de um T_ ou um _TAB .