• Brusque/SC
  • (47) 3053-7082
-
-

Blog

14 de maio de 2020

Checksum de fontes PL/SQL

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.

 

Postado por: Anderson Graf
200 visualizações

Compartilhe este post

Converse com a equipe Exímio

Encontre a melhor solução para sua empresa
Agende uma conversa com a nossa equipe!

Conteudo

Newsletter

Receba todas as nossas
novidades no seu e-mail