2008-11-12 9 views
5

Acabo de desperdiciar las dos últimas horas de mi vida tratando de crear una tabla con un aumento automático de las claves principales en this tutorial, El tutorial es genial, el problema que me he encontrado es que el objetivo de creación falla si tengo una columna que es una marca de tiempo y una tabla que se denomina marca de tiempo en la misma tabla ...Oracle ¿por qué falla la creación del disparador cuando hay un campo llamado marca de tiempo?

¿Por qué Oracle no señala esto como un problema cuando creo la tabla?

Aquí es la secuencia de comandos entro:

  1. Crear la tabla:

    CREATE TABLE myTable (ID de la llave número primario, campo1 marca de tiempo (6), NÚMERO timeStamp,

);

  1. Creación de la secuencia:

    CREATE SEQUENCE test_sequence START CON 1 incrementan en 1;

  2. Crear el gatillo:

    CREAR O SUSTITUIR TRIGGER test_trigger ANTES INSERT EN myTable referencia a nuevas AS NEW FOR EACH ROW COMENZAR test_sequence.nextval SELECT INTO: NEW.ID de la doble; END; /

Aquí está el mensaje de error que consigo:

ORA-06552: PL/SQL: Compilation unit analysis terminated 
ORA-06553: PLS-320: the declaration of the type of this expression is incomplete or malformed 

Cualquier combinación que no tiene las dos líneas con una la palabra "marca de tiempo" en ellos funciona bien. Pensé que la sintaxis sería suficiente para diferenciar entre la palabra clave y el nombre de una columna.

Como ya he dicho que no entiendo por qué se crea la tabla fina pero Oracle se cae cuando trato de crear el gatillo ...

CLARIFICACION

sé que la cuestión es que hay una columna llamada marca de tiempo que puede ser o no una palabra clave. MI problema es por qué se descompuso cuando intenté crear un activador y no cuando creé la tabla, al menos esperaba una advertencia.

Dicho esto, habiendo usado Oracle por algunas horas, parece mucho menos detallado en su informe de errores, tal vez solo porque estoy usando la versión expresa.

Si esto es un error en Oracle, ¿cómo alguien que no tiene un contrato de soporte puede informarlo? Solo estoy jugando con la versión express porque tengo que migrar algún código de MySQL a Oracle.

+0

Este problema es relativamente frustrante si tiene una base de datos anterior con una columna de tabla llamada 'timestamp' y desea agregar un desencadenador a ella. No he encontrado una forma de evitarlo, pero me temo. Sin embargo, he usado la respuesta de Pablo para problemas de nombres de marcas de tiempo similares. –

Respuesta

9

Hay una nota en metalink sobre esto (227615.1) extraer a continuación:

# symptom: Creating Trigger fails 
# symptom: Compiling a procedure fails 
# symptom: ORA-06552: PL/SQL: %s 
# symptom: ORA-06553: PLS-%s: %s  
# symptom: PLS-320: the declaration of the type of this expression is incomplete or malformed 
    # cause: One of the tables being references was created with a column name that is one of the datatypes (reserved key word). Even though the field is not referenced in the PL/SQL SQL statements, this error will still be produced. 

    fix: 

    Workaround: 

    1. Rename the column to a non-reserved word. 
    2. Create a view and alias the column to a different name. 
0

Bueno, no estoy totalmente seguro, pero creo que esto sucede porque el código SQL utilizado para manipular y acceder a los objetos de la base de datos es interpretado por algún intérprete diferente del que se usa para interpretar el código PL/SQL.

Tenga en cuenta que SQL y PL/SQL son cosas diferentes, por lo que se procesan de manera diferente. Entonces, creo que hay un error en un intérprete, pero no estoy seguro de cuál es.

1

Ha insinuado la respuesta usted mismo. Está utilizando timestamp como nombre de columna, pero también es una palabra clave. Cambia el nombre de la columna a algo más (por ejemplo, xtimestamp) y compila el disparador.

+1

Creo que lo entendió y su pregunta es "¿Por qué Oracle no generó un error cuando usé la palabra reservada en primer lugar?". Buena pregunta, creo. –

+0

Sí, más o menos, habría pensado que habría vomitado cuando creé la tabla y no cuando estaba creando el activador. –

+0

"ELIMINAR DE myTable" tampoco funcionará si tiene una columna llamada TIMESTAMP; necesita cambiar el nombre de la columna a otra cosa, hacer DELETE y cambiarle el nombre. Muy molesto. –

3

TIMESTAMP no figura en los documentos de Oracle como palabra reservada (lo cual es sorprendente).

Se muestra en la vista del diccionario de datos V $ RESERVED_WORDS, pero su bandera RESERVED está establecida en 'N'.

Podría ser un error en el procesamiento del disparador. Yo diría que este es uno bueno para el soporte de Oracle.

0

En lugar de tener Oracle mantener un punto de vista, utilizar EXECUTE IMMEDIATE (es decir, si 'Cambiar el nombre de la columna a una palabra no reservada' no es una opción.

0

puede ejecutar a través de EXECUTE IMMEDIATE. no es una mejor manera, pero el trabajo de cambiar el nombre de la columna y evitar.

En mi caso cambiar el nombre de la columna será una manera caótica

Cuestiones relacionadas