2009-07-24 29 views
15

Tengo una secuencia de comandos pl \ sql donde quiero establecer el nombre de la tabla utilizada en la secuencia de comandos para una variable. Entonces, de algunos ejemplos que encontré en la web, escribí el código a continuación. La primera sección funciona, entonces creo que mi sintaxis general es correcta, pero la segunda sección, donde intento usar una variable para un nombre de tabla, produce errores ("Error de SQL: ORA-00903: nombre de tabla no válida").cómo usar una variable en la secuencia de comandos oracle para el nombre de tabla

Alguien sabe lo que estoy haciendo mal ... No hago mucho PL \ SQL así que tal vez me esté perdiendo algo obvio.

--works 
variable numOfrecords number; 
exec :numOfrecords := 10; 
select * from customers2008 where rownum < :numOfrecords; 

--does not work 
variable tableNm CHAR; 
exec :tableNm := 'customers2008'; 
print tableNm; 
select * from :tableNm; 
+1

Solo FYI: En base a sus ejemplos, realmente no está usando PL/SQL. Creo que quieres decir que tienes un script SQLPlus. Técnicamente, los comandos de tu ejecutivo están llamando a PL/SQL, pero en general lo que estás mostrando aquí son los comandos de SQLPlus. –

+1

Bueno, técnicamente está usando ambos: el comando variable en el script declara una variable de vinculación PL/SQL. –

Respuesta

6

Substitution variables trabajo:

SQL> select * from &table_name; 
Enter value for table_name: dual 
old 1: select * from &table_name 
new 1: select * from dual 

D 
- 
X 
+0

¡Hah! Las grandes mentes piensan igual, incluso el enlace del documento es idéntico. –

+0

¡De hecho! Los enlaces son idénticos hasta el ancla :) –

14

Si está ejecutando este script desde sqlplus (que parece ser el caso), que desea utilizar el comando DEFINE, lo que le permite crear variables de sqlplus SUSTITUCIÓN que son sustitución de cadenas sólo directamente, por ejemplo:

define tableNm = 'customers2008' 
select * from &tableNm; 

Ver Using Sql*Plus para más información sobre cómo se utilizan estos. Puede pasar valores en su script desde la línea de comandos usando las variables predefinidas SUSTITUCIÓN posicionales, como esto:

define tableNm = &1 
select * from &tableNm; 

... y luego invocar sqlplus así:

sqlplus user/[email protected] @myscript.sql customers2008 

Si no lo hace pase un valor en la línea de comando, se le solicitará al invocador de scripts el valor.

Consulte la respuesta de Dave Costa a continuación para conocer las diferencias entre las variables de vinculación y sustitución.

+0

El único problema menor es que su ejemplo de invocación de SQLPlus no funciona (al menos para mí). Para pasar el valor en la línea de comando, debe llamar a un script, p. 'sqlplus user/pwd @ server @ mysyscript customers2008'. –

+0

¡De hecho! Editado y arreglado. –

+0

¡me encanta! ¡Qué bueno Steve! – CFNinja

8

Para tratar de añadir alguna explicación:

El método que se estaba tratando de usar que se llama un bind variables. Una variable de vinculación se identifica en Oracle SQL mediante dos puntos seguidos de un identificador. El propósito de una variable de vinculación es que su valor no necesita ser conocido al analizar la declaración de SQL; la declaración puede analizarse una vez y luego ejecutarse varias veces con diferentes valores vinculados a la variable.

Para analizar una instrucción SQL, se deben conocer los nombres de la tabla y columna involucrados. Por lo tanto, el nombre de la tabla no puede representarse mediante una variable de vinculación, ya que el valor no se conocería en el tiempo de análisis.

Si simplemente está ejecutando SQL y PL/SQl en línea a través de SQLPlus, entonces las variables de sustitución son una manera fácil de tratar este problema, como explicó Steve. Una variable de sustitución se reemplaza por su valor cuando el cliente SQLPlus lee el comando, incluso antes de enviarlo a Oracle para su análisis.

7

que tiene que hacer algo como esto:

EXECUTE IMMEDIATE 'select * from' || tableNm; 

Esto se debe a que Oracle no permite que las variables se unen para la mesa (o cualquier otro nombre de objeto).

Existen importantes implicaciones de seguridad con el enfoque EJECUTAR INMEDIATO: cuando el valor de tablaNm es proporcionado por el usuario, está muy abierto a los ataques SQL injection.

Cuestiones relacionadas