dbms_db_version pas de corps de package…

dbms_db_version est de ces packages qui ne contiennent ni procédures, ni fonctions et qui n’ont pas de corps. Vous n’y trouverez que constantes et commentaires. Vous trouverez dans cer article un truc de plus pour mystifier les DBA : constantes et variables PL/SQL ne peuvent pas être utilisées depuis une requête SQL.

Un package vide

Si vous utilisez la commande desc, vous constaterez avec un plaisir tout relatif que le package dbms_db_version semble vide :

desc dbms_db_version

[vide]

En fait, il n’en est rien, bien sur :

set pages 1000
select text
from dba_source
where name='DBMS_DB_VERSION'
and TYPE='PACKAGE'
order by LINE;

TEXT
--------------------------------------------------------------------------------
package dbms_db_version is
version constant pls_integer := 11; -- RDBMS version number
release constant pls_integer := 2; -- RDBMS release number

/* The following boolean constants follow a naming convention. Each
constant gives a name for a boolean expression. For example,
ver_le_9_1 represents version <= 9 and release <= 1
ver_le_10_2 represents version <= 10 and release <= 2
ver_le_10 represents version <= 10

A typical usage of these boolean constants is

$if dbms_db_version.ver_le_10 $then
version 10 and ealier code
$elsif dbms_db_version.ver_le_11 $then
version 11 code
$else
version 12 and later code
$end

This code structure will protect any reference to the code
for version 12. It also prevents the controlling package
constant dbms_db_version.ver_le_11 from being referenced
when the program is compiled under version 10. A similar
observation applies to version 11. This scheme works even
though the static constant ver_le_11 is not defined in
version 10 database because conditional compilation protects
the $elsif from evaluation if the dbms_db_version.ver_le_10 is
TRUE.
*/

ver_le_9_1 constant boolean := FALSE;
ver_le_9_2 constant boolean := FALSE;
ver_le_9 constant boolean := FALSE;
ver_le_10_1 constant boolean := FALSE;
ver_le_10_2 constant boolean := FALSE;
ver_le_10 constant boolean := FALSE;
ver_le_11_1 constant boolean := FALSE;
ver_le_11_2 constant boolean := TRUE;
ver_le_11 constant boolean := TRUE;

end dbms_db_version;

SQL, constantes et variables

Développez un package qui contient constantes et variables comme le package X ci-dessous :

create or replace package x is
c constant number := 1;
v number := 1;
function f return number;
end;
/

create or replace package body x is
function f return number is
begin
return c;
end;
end;
/

Vous constaterez avec plaisir que vous ne pouvez pas appeler la constante ou la variable depuis un programme PL/SQL:

select x.c from dual;
*
ERROR at line 1:
ORA-06553: PLS-221: 'C' is not a procedure or is undefined


select x.v from dual;
*
ERROR at line 1:
ORA-06553: PLS-221: 'V' is not a procedure or is undefined

Pourtant les mêmes variables et constantes peuvent être appelées depuis du code PL/SQL à l’intérieur ou même à l’extérieur de votre package :

var c number;
exec :c:=x.c;
select :c from dual;
:C
----------
1



select x.f from dual;

F
----------
1

Supprimez le package:

drop package body x;
drop package x;

Compilation conditionnelle

Tant qu’on est à parler de trucs à propos de dbms_db_version, j’ai vérifié que les compilations conditionnelles ne compilent pas le code qui n’est pas concerné par les conditions de compilation… On pouvait s’y attendre mais ça marche bien comme vous pouvez vous en rendre compte ci-dessous:

create or replace procedure x is
begin
$if dbms_db_version.ver_le_11 $then
dbms_output.put_line('Version 11!');
$else
<< Ecrire le code pour les autres versions ICI ! >>
$end
end;
/

set pages 1000
select text
from dba_source
where name='X'
and TYPE='PROCEDURE'
order by LINE;

TEXT
-----------------------------------------------------
procedure x is
begin
$if dbms_db_version.ver_le_11 $then
dbms_output.put_line('Version 11!');
$else
<< Ecrire le code pour les autres versions ICI ! >>
$end
end;


drop procedure x;

Et voilà, c’est presque tout : je voulais juste pointer un bug « rigolo » de la version 11.2.0.1 qui permet d’insérer 2 valeurs identiques dans un index unique ou dans une PK. Il fallait que ça tombe sur l’esprit dérangé d’Alex F.. En même temps, c’était téléphoné 😉 !

1 réflexion sur “dbms_db_version pas de corps de package…”

Les commentaires sont fermés.