martes, 17 de julio de 2007

Evitá el uso de Variables Globales

Veamos un ejemplo:


SQL_9iR2> CREATE OR REPLACE PACKAGE test_pkg
2 AS
3 PROCEDURE test_global_variable ;
4 END ;
5 /

Package created.

SQL_9iR2> CREATE OR REPLACE PACKAGE BODY test_pkg
2 AS
3 variable_globar NUMBER ;
4 PROCEDURE mostrar_variable_global ( p_valor IN NUMBER )
5 IS
6 BEGIN
7 dbms_output.put_line( 'Valor de la variable global: '||p_valor ) ;
8 variable_globar := 2 ;
9 dbms_output.put_line( 'Valor de la variable global: '||p_valor ) ;
10 END ;
11
12 PROCEDURE test_global_variable
13 IS
14 BEGIN
15 variable_globar := 1 ;
16 mostrar_variable_global(variable_globar) ;
17 END ;
18
19 END test_pkg ;
20 /

Package body created.


SQL_9iR2> EXEC test_pkg.test_global_variable ;
Valor de la variable global: 1
Valor de la variable global: 2


PL/SQL procedure successfully completed.


Cómo puede ser ésto posible? Bueno, como los valores IN se pasan por referencia, el valor de la variable global también es pasada al procedimiento mostrar_variable_global por referencia.

Para evitar éste problema con las variables globales tenemos 2 opciones:
1) No usar Variables Globales :)
2) Si estamos forzados a utilizarlas, podemos asignar el contenido de la variable global a una nueva variable y pasar el valor de esa nueva variable como parámetro. Sino, podemos modificar el input del parámetro.

Veamos las 2 opciones implementadas:

- Opción 1:

SQL_9iR2> CREATE OR REPLACE PACKAGE test_pkg
2 AS
3 PROCEDURE test_global_variable ;
4 END test_pkg ;
5 /

Package created.

SQL_9iR2> CREATE OR REPLACE PACKAGE BODY test_pkg
2 AS
3 variable_globar NUMBER ;
4 PROCEDURE mostrar_variable_global ( p_valor IN NUMBER )
5 IS
6 BEGIN
7 dbms_output.put_line( 'Valor de la variable global: '||p_valor ) ;
8 variable_globar := 2 ;
9 dbms_output.put_line( 'Valor de la variable global: '||p_valor ) ;
10 END ;
11
12 PROCEDURE test_global_variable
13 IS
14 l_variable_global_aux NUMBER ;
15 BEGIN
16 variable_globar := 1 ;
17 l_variable_global_aux := variable_globar ;
18 mostrar_variable_global(l_variable_global_aux) ;
19 END ;
20
21 END test_pkg ;
22 /

Package body created.


SQL_9iR2> EXEC test_pkg.test_global_variable ;
Valor de la variable global: 1
Valor de la variable global: 1



- Opción 2:

SQL_9iR2> CREATE OR REPLACE PACKAGE test_pkg
2 AS
3 PROCEDURE test_global_variable ;
4 END test_pkg ;
5 /

Package created.

SQL_9iR2> CREATE OR REPLACE PACKAGE BODY test_pkg
2 AS
3 variable_globar NUMBER ;
4 PROCEDURE mostrar_variable_global ( p_valor IN NUMBER )
5 IS
6 BEGIN
7 dbms_output.put_line( 'Valor de la variable global: '||p_valor ) ;
8 variable_globar := 2 ;
9 dbms_output.put_line( 'Valor de la variable global: '||p_valor ) ;
10 END ;
11
12 PROCEDURE test_global_variable
13 IS
14 BEGIN
15 variable_globar := 1 ;
16 mostrar_variable_global(variable_globar+0) ;
17 END ;
18
19 END test_pkg ;
20 /

Package body created.


SQL_9iR2> EXEC test_pkg.test_global_variable ;
Valor de la variable global: 1
Valor de la variable global: 1


PL/SQL procedure successfully completed.

No hay comentarios.: