2009-08-06 15 views
5

Estoy tratando de ejecutar varias sentencias ddl dentro de una sentencia Execute Inmediate. pensé que esto sería bastante directo pero parece que estoy equivocado.ORACLE Enumeración de sentencias DDL dentro de Execute Inmediato

La idea es la siguiente:

declare v_cnt number; 

begin 

select count(*) into v_cnt from all_tables where table_name='TABLE1' and owner = 'AMS'; 

if v_cnt = 0 then 

execute immediate 'CREATE TABLE TABLE1(VALUE VARCHAR2(50) NOT NULL) ALTER TABLE TABLE1 ADD (MYVAL2 NVARCHAR2(10))'; 

end if; 

end; 

sin embargo, esto resulta en un error

ORA-00911: carácter no válido ORA-06512: en la línea 10

Cada una de las instrucciones dentro del lote funcionan bien si las ejecuto por sí mismas. y si tomo esta declaración y la ejecuto, correrá bien (con el; entre las 2 declaraciones). Si elimino el; entre las declaraciones me sale un error diferente sobre la opción no válida

el plan es que seré capaz de construir una tabla, exportar el esquema de la tabla para esta tabla incluyendo todas las declaraciones alter, y luego ejecutar el lote contra otro sistema como parte de un proceso de instalación/actualización.

Entonces, ¿cómo puedo agrupar estas sentencias DDL en una sola ejecución inmediata? ¿O hay una mejor manera de hacer lo que estoy necesitando?

Soy un poco nuevo de Oracle, debo admitirlo. Gracias a todos por su paciencia.

Respuesta

2

¿Por qué necesita una sola llamada EXECUTE INMEDIATA? Seguramente solo hazlo como 2 llamadas?

Tenga en cuenta que cada instrucción DDL contiene un COMPROMISO implícito, por lo que no hay beneficio de concurencia para hacerlo como una sola llamada.

Además, ¿por qué no simplemente configurar la tabla correctamente en la primera llamada? Se podría hacer ...

CREAR tabla Tabla1 (VALOR VARCHAR2 (50) NOT NULL, MYVAL2 NVARCHAR2 (10))

... en lugar de tener 2 llamadas.

Además, ha mirado DBMS_METADATA ... puede generar DDL para objetos como tablas para usted.

+0

la creación y las modificaciones de la tabla se exportan como un solo archivo y en este momento, hay suficientes como para que valga la pena tratar de hacerlo en 1 EJECUTAR INMEDIATO frente a muchos objetos por db. – Beta033

+0

En cuyo caso, sugeriría simplemente generar el DDL correcto en primer lugar. Mira DBMS_METADATA. :-) – cagcowboy

+0

parece que esto puede solucionar mi problema. lamentablemente, la respuesta obvia estaba debajo de mis narices. Lección aprendida: No use TOAD en la estructura de salida aunque haya un elegante menú de gui para ello. – Beta033

4

El punto y coma no es parte de la sintaxis SQL de Oracle. SQL * Plus y otras herramientas del lado del cliente usan punto y coma para señalar el final de una instrucción SQL, pero el servidor no la ve.

Podemos forzar SQL * Plus para pasar el punto y coma al DB:

SQL> set sqlterminator off 
SQL> select * from user_tables; 
    2/
select * from user_tables; 
         * 
ERROR at line 1: 
ORA-00911: invalid character 

Si tomo esta declaración y ejecutarlo, se ejecutará bien (con la; entre los 2 estados) El herramienta de cliente que está utilizando, la divide en dos llamadas a la base de datos.

Por lo tanto, no creo que sea posible pasar varias instrucciones dentro de una ejecución inmediata.

Supongo que se podría ejecutar ejecutar inmediatamente con una cadena que contenga un bloque PL/SQL anónimo, con llamadas individuales para ejecutar inmediatamente dentro de él ... y no sé cuál sería el objetivo de hacerlo.;)

+0

Mi experiencia es la misma: no podemos pasar múltiples instrucciones dentro de un 'EXECUTE INMEDIATO'. – Baodad

Cuestiones relacionadas