Assim como temos em ambientes Linux o cksum e o sha1sum que nos permitem gerar um código hash para a comparação de consistência de um arquivo, umas das opções no Oracle Database é a função GET_HASH_VALUE disponível no pacote DBMS_UTILITY que permite gerar um código hash do fonte sendo muito útil para identificar se ele está consistente ou se houve alguma alteração, principalmente quando comparamos extensos códigos PL/SQL que visivelmente daria trabalho para determinar se estão iguais entre uma base de dados e outra, por exemplo.
Criando uma procedure de exemplo e obtendo o hash:
SQL> create or replace procedure exemplo as 2 begin 3 null; 4 end; 5 / Procedure created. SQL> SELECT AVG(DBMS_UTILITY.GET_HASH_VALUE(TEXT,1000000000,POWER(2,30))) AS CHECKSUM FROM DBA_SOURCE WHERE OWNER = 'SYS' AND NAME ='EXEMPLO'; CHECKSUM ---------- 1742638361
Agora recriando a procedure incluindo apenas um espaço entre o null e o ; (ponto e virgula)
SQL> create or replace procedure exemplo as 2 begin 3 null ; 4 end; 5 / Procedure created. SQL> SELECT AVG(DBMS_UTILITY.GET_HASH_VALUE(TEXT,1000000000,POWER(2,30))) AS CHECKSUM FROM DBA_SOURCE WHERE OWNER = 'SYS' AND NAME ='EXEMPLO'; CHECKSUM ---------- 1701853948
Com a inserção de apenas um espaço já podemos constatar que o hash dela já não é igual ao hash do PL/SQL anterior indicando assim que o fonte é diferente.
Recriando a procedure da forma que era originalmente iremos voltar a ter o mesmo hash 1742638361
SQL> create or replace procedure exemplo as 2 begin 3 null; 4 end; 5 / Procedure created. SQL> SELECT AVG(DBMS_UTILITY.GET_HASH_VALUE(TEXT,1000000000,POWER(2,30))) AS CHECKSUM FROM DBA_SOURCE WHERE OWNER = 'SYS' AND NAME ='EXEMPLO'; CHECKSUM ---------- 1742638361
Outro método para se obter o hash de um PL/SQL é através do pacote DBMS_CRYPTO
SQL> set serveroutput on
SQL> declare
2
3 string varchar2(32767);
4 l_hash raw(2000);
5 lvschema VARCHAR2(30) :='SYS';
6 lvname VARCHAR2(30) :='EXEMPLO';
7 lvtype varchar2(30) :='PROCEDURE';
8
9 begin
10
11 l_hash:=dbms_crypto.hash(dbms_metadata.get_ddl(lvtype, lvname, lvschema), dbms_crypto.hash_sh1);
12 dbms_output.put_line('HashSHA1='||l_hash||' Name='||lvschema||'.'||lvname);
13
14 end;
15 /
HashSHA1=859EEB0AEE5CF93CF9507951E7446D6EAD958885 Name=SYS.EXEMPLO
PL/SQL procedure successfully completed.
Espero que a dica possa ser útil para você também.


0 comentários:
Postar um comentário