quinta-feira, 26 de novembro de 2009

Importação de Base de Dados no Banco XE

Muitas pessoas ainda tem dúvida de como importar um dump exportado via data pump, então logo abaixo coloco uma forma rápida para conseguir isso.

1º coloque seu arquivo de dump na pasta (Oracle XE Home)\app\oracle\admin\xe\dpdump\

2º execute o comando abaixo no prompt do seu sistema operacional, trocando os campos em () pelos valores correspondentes
impdp (user DBA)@(nome banco) dumpfile=(nome arquivo de dump a ser importado).dmp logfile=(nome do arquivo de log de importação).log remap_schema=(schema que foi exportado):(schema imp) remap_tablespace=(tablespace que foi exportado):(tablespace que vai ser importado) transform=oid:n:type

3º Aguarde... Pronto, você acaba de fazer uma importação de um banco de dados!




segunda-feira, 26 de outubro de 2009

Obtendo o primeiro dia do mês

Como no oracle existe a função last_day, e não existe uma 'first_day', muitas vezes nos deparamos com códigos para obter o primeiro dia do mês, quando existe o comando trunc que nos dá isso de barbada! Observe:

SQL> select trunc(sysdate,'mm') from dual
2 /

TRUNC(SY
--------
01/10/09

o mesmo vale para o primeiro dia do ano:

SQL> select trunc(sysdate,'rrrr') from dual
2 /

TRUNC(SY
--------
01/01/09

quinta-feira, 15 de outubro de 2009

Manipulação de tabelas de memória

Muitas vezes temos que trabalhar com tabelas de memória para manipular dados. Existem vários tipos de tabela, sendo a mais comumente utilizada a que indexa os registro por um inteiro binário (binary_integer).

Para o uso desta tabela, encontramos um pequeno problema quando temos que deletar um registro qualquer desta tabela, visto que ai, a mesma acaba perdendo a sequencia da indexação... veja o exemplo:

SQL> DECLARE
2 TYPE T_A IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;
3 V_A T_A;
4 BEGIN
5 FOR I IN 1..10
6 LOOP
7 V_A(I) := 'A - '||I;
8 END LOOP;
9 V_A.DELETE(3);
10 FOR I IN V_A.FIRST..V_A.LAST
11 LOOP
12 DBMS_OUTPUT.PUT_LINE( V_A(I));
13 END LOOP;
14 END;
15 /
A - 1
A - 2
DECLARE
*
ERRO na linha 1:
ORA-01403: no data found
ORA-06512: at line 12


Neste exemplo, eu criei uma tabela de memória, e inicializei com 10 registros. Logo após, deletei o terceiro registro, para simular, e mandei mostrar os registros constantes na tabela. Note que no momento que o programa chegou no registro faltante, ele deu um erro de no data found.
Sendo assim, mesmo usando a varredura da tabela de memória do first para o last, ele ainda varre todos os indices, inclusive aquele que já foi deletado!!!

Isto pode ser resolvido facilmente, usando a função exists da tabela de memória, como no exemplo abaixo:

SQL> DECLARE
2 TYPE T_A IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER;
3 V_A T_A;
4 BEGIN
5 FOR I IN 1..10
6 LOOP
7 V_A(I) := 'A - '||I;
8 END LOOP;
9 V_A.DELETE(3);
10 FOR I IN V_A.FIRST..V_A.LAST
11 LOOP
12 IF V_A.EXISTS(I) THEN
13 DBMS_OUTPUT.PUT_LINE( V_A(I));
14 END IF;
15 END LOOP;
16 END;
17 /
A - 1
A - 2
A - 4
A - 5
A - 6
A - 7
A - 8
A - 9
A - 10

Procedimento PL/SQL concluído com sucesso.

quarta-feira, 14 de outubro de 2009

Cuidado com o lpad/rpad

Bom, todos que trabalham com oracle, já tiveram que alguma vez usar as funções de complementação de caracteres (lpad/rpad). Ela basicamente serve para preencher um variável ou coluna string com um caracter até obter o tamanho desejado, como no exemplo abaixo:

SQL> select lpad('alguma coisa',20,'x') from dual
2 /

LPAD('ALGUMACOISA',2
--------------------
xxxxxxxxalguma coisa


Mas o que pouca gente sabe, é que dependendo do parâmetro de entrada destas funções, ela pode retornar alguns resultados diferentes do desejado, como quando o primeiro parâmetro passado for nulo. Neste caso, a função retorna nula, como se pode diagnosticar no exemplo abaixo:

SQL> select lpad(null,20,'x') from dual
2 /

L
-


Ou seja, eu pedi para função preencher até 20 caracteres com x, mas ela me retornou nula!!!

Portanto, como geralmente o parâmetro de entrada é usado com alguma coluna do banco, sugiro usar a função nvl para se certificar que a função, mesmo no caso da coluna ser nula, retorne o campo formatado conforme desejado. Observe:

SQL> select lpad(nvl(null,'a'),20,'x') from dual
2 /

LPAD(NVL(NULL,'A'),2
--------------------
xxxxxxxxxxxxxxxxxxxa


o mesmo vale para o parâmetro de complemento, como no exemplo abaixo:

SQL> select lpad('a',20,null) from dual
2 /

L
-


Ou seja, se o parâmetro for nulo, também a função irá retornar nulo...

Há, muito importante, se tiver que colocar um número x de zeros ou qualquer outro caracter repetido, não repita o valor, por favor, use lpad/rpad, observe:

SQL> select lpad('0',20,'0') from dual
2 /

LPAD('0',20,'0')
--------------------
00000000000000000000

Teste Unitário em geração de Arquivos

Vejo hoje em dia muitos desenvolvedores que apenas partem do pressuposto, que se a saida está de acordo com o documento de análise, então o programa está concluido. Só que eles não se atentam para o fato de que o analista é humano, e portanto, também está sujeito a cometer falhas no seu processo. Por isso se torna cada vez mais necessário, que o desenvolvedor entenda o que está fazendo, e qual o resultado esperado para o procedimento que ele está concluido.
Tomemos como exemplo uma geração de arquivo texto posicional, onde, com base no layout passado, o desenvolvedor faz o programa de extração dos dados da base, e posterior formatação para o arquivo texto. Após finalizado o desenvolvimento, o programador dá uma rápida conferida, e ai, qual o próximo passo: entregar o procedimento?
Se ele tiver um arquivo texto de exemplo no layout que desenvolveu, pode fazer uma rápida comparação entre a saida do seu programa e o exemplo passado, e com isto, detectar inúmeros problemas que só seriam vistos mais pra frente, como deslocamento de campos, alinhamento de colunas, preenchimentos das demais posições, falta de informações que ocasionaram deslocamento de campos. Ou seja, um simples teste, detecta inúmeros bugs e faz com que o desenvolvedor possa atingir uma qualidade muito maior no produto (software) que ele desenvolveu.

quinta-feira, 8 de outubro de 2009

Utilização de funções analiticas

Bom, hoje irei falar sobre uma função analitica que a um bom tempo não usava, mas que ontem me foi bem util. Trata-se da função over partition do Oracle, a qual pode ser conferida no exemplo abaixo:

Ela 'reinicializa' a contagem do campo seq de acordo com o parametro passado no partition by.

Aguardo sugestões para os próximos posts...

segunda-feira, 2 de junho de 2008

Oracle XE + forms 6i

Um cliente, a pouco tempo, me pediu um pequeno sistema para controlar seus projetos. Estudando o caso, optei por desenvolve-lo utilizando a ferramenta Oracle Forms na versão 6i. Para o banco de dados, optei pelo Oracle XE, pelo fato de o mesmo não apresentar custo para bancos pequenos, até 4 GB.

Só que no momento de integrar os dois, aconteceu algo inexperado. Eles não comunicavam. Configurei o tnsnames e nada. Não tinha jeito. Neste momento, só me restou uma alternativa: Google IT. E após pesquisar um pouco, encontrei uma solução que em primeiro momento me pareceu estapafúrdia, mas que veio a salvar meu projeto. O forms 6i não comunica com a versão universal do oracle XE, não sei porquê, mas somente com a versão Western do Oracle XE. Desintalei a versão universal, baixei a western e instalei. E por um passe de mágica, passou a funcionar...

Logo após, fui testar a comunicação remota, instalei em outra máquina o cliente do oracle XE e nada do mesmo comunicar novamente. E para minha surpresa, CADÊ O TNSNAMES???
Dai novamente fui atrás dos sábios conhecimentos da grande rede. E lá encontrei que a versão XE não necessita mais do tnsnames, é só passar no lugar do db o ip e serviço, ao invés do serviço do tnsnames. Testei isso e nada de conectar. Deixo para meus caros colegas a tentativa de fazer o teste. Se funcionar, postem aqui suas soluções...
Depois de conversar com o milton do grupo amigos_oracle pelo MSN, ele me chamou a atenção para o real problema. A rede. Sim, era a rede, o maldito firewall do windows, que trancava a conecção. Foi só liberar a porta 1521 do servidor, que novamente por mágica, o forms conectou, claro que desta vez utilizando o tnsnames da pasta orant que o runtime do forms 6i instalou para mim, e que eu modifiquei...

E esta foi a minha saga com o Oracle XE. Espero que os tentem se aventurar com este banco leiam este relato para não passar tantos percausos para conseguir comunicar com o mesmo...