miércoles, 24 de agosto de 2011

Variables de paquetes edicionados

¿Que ocurre con los valores de las variables públicas en paquetes que tienen varias ediciones?

Esta fue una pregunta del público (gracias Victoria!) al final de mi charla sobre 11gR2 en la JIAP, explorando las posibilidades de la nueva funcionalidad Edition-Based Redefinition (EBR).

Aprovecho a desarrollar un ejemplo simple que muestra este comportamiento, donde se comprueba que cada edición del paquete mantiene su estado. Está aclarado en el manual aquí.

Esto es algo más a considerar si pensamos usar EBR para hacer actualización de versiones de aplicativos y minimizar el tiempo en que la aplicación está fuera de línea.

Este ejemplo es usando 11.2.0.2 enterprise:

1) Levantamos la base:


oracle@oraculo:~> sqlplus / as sysdba

SQL*Plus: Release 11.2.0.2.0 Production on Wed Aug 24 00:02:33 2011

Copyright (c) 1982, 2010, Oracle. All rights reserved.


Connected to an idle instance.

SQL> startup

ORACLE instance started.

Total System Global Area 1043886080 bytes
Fixed Size 2233088 bytes
Variable Size 645926144 bytes
Database Buffers 390070272 bytes
Redo Buffers 5656576 bytes
Database mounted.
Database opened.

SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE 11.2.0.2.0 Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production


Creamos usuario para hacer la prueba

SQL> create user pru identified by pru;

User created.

SQL> grant dba to pru;

Grant succeeded.


Habilitamos EBR:

SQL> ALTER USER pru ENABLE EDITIONS;

User altered.

SQL> conn pru/pru
Connected.


Creamos el paquete PP con la variable VN y un par de procedimientos para incrementar y mostrar su valor:

SQL> create or replace package pp as
-- variable pública
vn number;
--procedimientos que usan la variable
procedure muestro;
procedure suma (n in number);
end;
/

Package created.

SQL> create or replace package body pp as
procedure muestro is
begin
dbms_output.put_line('vn vale: '||pp.vn);
end;
procedure suma (n in number) is
begin
pp.vn := nvl(pp.vn,0) + n;
end;
end;
/

Package body created.


Vemos en que edición quedó creado:

SQL> select edition_name, name, max(line)
from DBA_SOURCE_AE
where name = 'PP'
group by edition_name, name;

EDITION_NAME NAME MAX(LINE)
------------------------------ ------------------------------ ----------
ORA$BASE PP 13


Cargamos el valor 5 en la variable:

SQL> set serveroutput on;
SQL> exec pp.suma(5);

PL/SQL procedure successfully completed.

SQL> exec pp.muestro;
vn vale: 5

PL/SQL procedure successfully completed.


Ahora creamos una nueva edición y trabajamos en ella:

SQL> create edition e0;

Edition created.

SQL> ALTER SESSION SET EDITION = e0;

Session altered.


No creamos nada todavía, así que el paquete sigue siendo el original.
¿Cuanto vale la variable?. Sumamos uno y vemos:

SQL> exec pp.suma(1);

PL/SQL procedure successfully completed.

SQL> exec pp.muestro;
vn vale: 1

PL/SQL procedure successfully completed.


No se mantiene el valor que cargamos en la edición anterior (5), sino que se inicializó en esta edición.

Validamos en qué edición estamos trabajando:

SQL> SELECT SYS_CONTEXT('USERENV', 'CURRENT_EDITION_NAME'),
SYS_CONTEXT('USERENV', 'SESSION_EDITION_NAME')
FROM DUAL;

SYS_CONTEXT('USERENV','CURRENT_EDITION_NAME')
--------------------------------------------------------------------------------
SYS_CONTEXT('USERENV','SESSION_EDITION_NAME')
--------------------------------------------------------------------------------
E0
E0


Ahora cambiamos el código del paquete en esta edición, para poder diferenciarlo del anterior.

El texto desplegado incluye "2.0" y suma el doble de lo que se pide.
SQL> create or replace package pp as
vn number := 0;
procedure muestro;
procedure suma (n in number);
end;
/

Package created.

SQL> create or replace package body pp as
procedure muestro is
begin
dbms_output.put_line('vn 2.0 vale: '||pp.vn);
end;

procedure suma (n in number) is
begin
pp.vn := nvl(pp.vn,0) + n*2;
end;
end;
/

Package body created.



Comprobamos las versiones existentes del paquete

SQL> select edition_name, name, max(line)
from DBA_SOURCE_AE
where name = 'PP'
group by edition_name, name;

EDITION_NAME NAME MAX(LINE)
------------------------------ ------------------------------ ----------
ORA$BASE PP 13
E0 PP 13


Nuevamente incrementamos la variable global del paquete en esta edición

SQL> exec pp.suma(1);

PL/SQL procedure successfully completed.

SQL> exec pp.muestro;
vn 2.0 vale: 2

PL/SQL procedure successfully completed.


En resumen:
  • valía 5 en la edición ORA$BASE.
  • 1 en E0 cuando no se había cambiado.
  • luego de crear la nueva versión en E0 las variables se inicializan, y ahora vale 2.
Vuelvo a la edición original e incremento de nuevo para confirmar que mantiene su valor

SQL> ALTER SESSION SET EDITION = ORA$BASE;

Session altered.

SQL> exec pp.suma(1);

PL/SQL procedure successfully completed.

SQL> exec pp.muestro;
vn vale: 6

PL/SQL procedure successfully completed.


jueves, 18 de agosto de 2011

Presentación sobre 11gR2

Ayer comenzaron las jornadas anuales de la Asociación de Informáticos de la Administración Pública (AsIAP) en Montevideo, evento más conocido como la JIAP.

Propuse una charla sobre 11gR2 en nombre del UYOUG, que fue aceptada y presenté ayer.

Les dejo la presentación.


Saludos.

domingo, 31 de julio de 2011

¿Que nos mantiene ocupados?

Todavía no encontré la rutina que me permita mantener este blog actualizado. Y no es por falta de material para compartir, sino las muchas cosas que están pasando este año.

La más reciente es la más destacada hasta ahora, por el esfuerzo que fue mucho, y por el gran éxito: el UYOUG OTN Tour Montevideo.

Fueron más de 100 asistentes, siete expositores extranjeros que dieron charlas de excelente nivel, y el privilegio de compartir unos días con mejores personas.

Como ya tratamos de decirlo en las entrevistas a pesar de los nervios, estamos muy agradecidos con todos los que entendieron que este tipo de eventos no es algo de todos los días en nuestro medio, y que deben ser apoyados para que tengan continuidad.
Así que una vez más: gracias a todos los que se arrimaron a pesar del mal tiempo, a las empresas que nos auspiciaron, a OTN y los expositores que vinieron.

Tenemos planes de hacer un evento local antes de fin de año, así que en breve habrán novedades.

En estos días vamos a publicar todas las presentaciones en el sitio.
Mientras, les dejo la mía.




Saludos