2009-09-21 25 views
7

Supongamos que tengo los esquemas A y B.Oracle: desambiguación entre la tabla y el nombre del esquema

En el esquema A me gustaría llamar al paquete X en el esquema B. Sin embargo, existe un paquete B en el esquema A.

A: 
    package B 
B: 
    package X 

Cuando llamo a partir del esquema A:

begin b.x.foo(); end 

busca X procedimiento en el paquete B, es decir A.B.X(), y obtiene un error.

¿Cómo califico completamente la llamada para forzar que B se considere un nombre de esquema?

actualización:

  • Parece que no hay manera de alcance la referencia para referirse a b.x.foo.
  • CREATE SYNONYM B_X for B.X funciona. B_X.foo() llama al procedimiento en el esquema B.
+0

¿Podría crear un sinónimo en A que apunte a BX que tiene un nombre inequívoco? Aunque puede darte el mismo problema. – skaffman

Respuesta

7

No creo que pueda hacerlo. A partir de las "Las reglas de resolución de nombres PL/SQL User's Guide:

de PL/SQL y SQL son similares. Puede evitar las pocas diferencias si se siguen las normas de prevención de captura. Por razones de compatibilidad, las reglas de SQL son más permisivos que las reglas de PL/SQL . normas SQL, que en su mayoría son sensibles al contexto, reconocen más situaciones como legales y las instrucciones DML que las reglas de PL/SQL.

  • PL/SQL utiliza las mismas reglas de resolución de nombres como SQL cuando los procesos de compilación PL/SQL una instrucción SQL, como una declaración DML. Por ejemplo, para un nombre como HR.JOBS, SQL hace coincidir los objetos en el esquema HR primero, luego paquetes, tipos, tablas y vistas en el esquema actual.
  • PL/SQL utiliza un orden diferente para resolver nombres en sentencias PL/SQL como asignaciones y llamadas a procedimientos. En el caso de un nombre HR.JOBS, PL/SQL busca en primer lugar para los paquetes, tipos, tablas y vistas guardadas de recursos humanos en el esquema actual, después de los objetos en el esquema HR."

El segundo punto anterior se aplica. Dado que el objeto "B" existe en el esquema A, eso es lo que resuelve la referencia.

3

Estoy de acuerdo con DCookie, aunque este es un problema de alcance normal. problema sería cambiar el CURRENT_SCHEMA:

SQL> exec b.x.foo; 

begin b.x.foo; end; 

ORA-06550: line 2, column 9: 
PLS-00302: component 'X' must be declared 
ORA-06550: line 2, column 7: 
PL/SQL: Statement ignored 

SQL> alter session set current_schema=b; 

Session altered 

SQL> exec b.x.foo; 

PL/SQL procedure successfully completed 
+0

+1 buena solución – skaffman

+0

Esto solo funciona si configura el esquema actual antes de ejecutar el bloque PL/SQL, y por lo tanto es efectivo para todo el bloque. No puede ejecutar la sesión de modificación dentro del bloque PL/SQL. Si eso no es un problema, entonces esto funciona. – DCookie

+0

@DCookie: Esta es solo una solución simple: la verdadera solución sería diseñar un esquema de nombres que evite este tipo de colisión de nombres –

Cuestiones relacionadas