Wednesday, October 18, 2006
PRAGMA AUTONOMOUS_TRANSACTION
O pragma autonomous_transaction pode ser usado para capturar erros durante a execução mesmo após um rollback. Fiz um exemplo muito simples para um colega hoje.
Explicando o teste: a tabela "t_errors" receberá o erro da divisão por zero, porém há um insert antes que não se efetivará pelo saída de exceção "WHEN OTHERS" e, claro, não podia deixar de demonstrar como usar o WHEN OTHERS corretamente, ou seja, com um RAISE no final!
Esse teste me renderá 4 chopps! :-)
Explicando o teste: a tabela "t_errors" receberá o erro da divisão por zero, porém há um insert antes que não se efetivará pelo saída de exceção "WHEN OTHERS" e, claro, não podia deixar de demonstrar como usar o WHEN OTHERS corretamente, ou seja, com um RAISE no final!
Esse teste me renderá 4 chopps! :-)
ops$marcio@LUKE9I> create table t_errors (
2 dt date,
3 x varchar2(4000)
4 );
Table created.
ops$marcio@LUKE9I> create table t ( dt date );
Table created.
ops$marcio@LUKE9I> select * from t;
no rows selected
ops$marcio@LUKE9I> select * from t_errors;
no rows selected
ops$marcio@LUKE9I> declare
2 l_number number;
3 procedure err ( p_errmsg in varchar2 )
4 is
5 PRAGMA AUTONOMOUS_TRANSACTION;
6 begin
7 insert into t_errors values ( sysdate, p_errmsg );
8 commit;
9 end;
10 begin
11 insert into t values ( sysdate );
12 l_number := 10/0;
13 commit;
14 exception
15 when others then
16 rollback;
17 err( sqlerrm );
18 raise;
19 end;
20 /
declare
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at line 18
ops$marcio@LUKE9I> select * from t;
no rows selected
ops$marcio@LUKE9I> select * from t_errors;
DT X
------------------- ------------------------------------------------------------
18/10/2006 01:11:44 ORA-01476: divisor is equal to zero
1 row selected.
Labels: how to
Tuesday, October 03, 2006
Separação de String
Outro dia respondi uma dúvida em um forum e achei interessante para compartilhar.
A dúvida
Primeiro, vou reproduzir exatamente o exemplo dado.
Ex.
A dúvida
Gostaria de saber com criar uma funcao que faca o seguinte:
separe um codigo em prefixo, medida e sulfixo.
os codigos podem ter o seginte formato
XXX9999YYY
XX9999999YY
XXXX99
sedo que:
X é o prefixo e eh sempre um conjunto de caracteres
9 é a medida e eh sempre numerico
Y é o sulfixo, sempre caracteres, podendo existir ou nao.
o tamanho de cada cadeia de caracteres pode variar, ex:
XXXX; XXX; XX; XXXXX
999; 9999; 99999
YY; YYY; YYYYYY ou sem caracter.
Primeiro, vou reproduzir exatamente o exemplo dado.
ops$marcio:YODA10G> create table t ( x varchar2(15) );Abaixo, a técnica: Vejo se consigo encontrar a posição onde começa e termina os numerais. Portanto:
Table created.
ops$marcio:YODA10G> insert into t values ( 'XXX9999YYY' );
1 row created.
ops$marcio:YODA10G> insert into t values ( 'XX9999999YY' );
1 row created.
ops$marcio:YODA10G> insert into t values ( 'XXXX99' );
1 row created.
XXX9999YYYPor que necessito disso? Porque eu poderei separar facilmente os valores usando a função SUBSTR mais a frente. A substr pede inicio e quantidade de bytes a separar, com o inicio e fim dos numeros na string, basta subtrair que terei o tamanho dos numeros.
1234567890 = Incio,fim (4,7)
XX9999999YY
12345678901 = Inicio,fim (3,9)
Ex.
XXX9999YYY
1234567890 = Incio,fim (4,7)
tam=fim-inicio = tam=7-4; tam=3 (+1 da posição inicial).
A substr, começanda a posição 4, extraindo
4 bytes são exatamente os numeros que estão
compreendidos na string.
XXX9999YYY
+--+
1234 ----------= *posição inicial do SUBSTR + 4 bytes (9999).
Demonstrando:ops$marcio:YODA10G>
ops$marcio:YODA10G> select x,
2 instr(n, '9' ) prm,
3 instr(n, '9', -1) ult
4 from (
5 select translate(x,'1234567890','9999999999') n, x
6 from t
7 )
8 /
X PRM ULT
--------------- ------------- -------------
XXX9999YYY 4 7
XX9999999YY 3 9
XXXX99 5 6
3 rows selected.
ops$marcio:YODA10G>
ops$marcio:YODA10G> select x
2 , substr(x, 1, instr(n,'9')-1 ) prefixo
3 , substr(x, instr(n,'9'), (instr(n,'9', -1)+1) - instr(n,'9')) medida
4 , substr(x, instr(n,'9', -1)+1 ) sulfixo
5 from ( select x, translate(x,'1234567890','9999999999') n from t )
6 /
X PREFIXO MEDIDA SULFIXO
--------------- --------------- --------------- ---------------
XXX9999YYY XXX 9999 YYY
XX9999999YY XX 9999999 YY
XXXX99 XXXX 99
3 rows selected.
Agora incrementando o teste para que a query acima seja verdade.
ops$marcio:YODA10G> insert into t values ( 'ab1234567vc');
1 row created.
ops$marcio:YODA10G> insert into t values ( 'mn0z');
1 row created.
ops$marcio:YODA10G> insert into t values ( 'ooo123');
1 row created.
ops$marcio:YODA10G> select x
2 , substr(x, 1, instr(n,'9')-1 ) prefixo
3 , substr(x, instr(n,'9'), (instr(n,'9', -1)+1) - instr(n,'9')) medida
4 , substr(x, instr(n,'9', -1)+1 ) sulfixo
5 from ( select x, translate(x,'1234567890','9999999999') n from t )
6 /
X PREFIXO MEDIDA SULFIXO
--------------- --------------- --------------- ---------------
XXX9999YYY XXX 9999 YYY
XX9999999YY XX 9999999 YY
XXXX99 XXXX 99
ab1234567vc ab 1234567 vc
mn0z mn 0 z
ooo123 ooo 123
6 rows selected.
ops$marcio:YODA10G>
Labels: how to
Setup de Linux para ASM (ASMLibs)
Instalação ASMLib
Vou até o /mnt/xp, onde já estão as bibliotecas do ASMLib e vou instalar de lá os rpms. Tenho que instalar como root.
Próximo passo é investigar quais serão os discos para serem criados no ASM, para isso vou usar o fdisk. No meu caso, eu deixei para plugar 2 discos depois da instalação por isso que no output abaixo, não encontramos os discos. Terei que ir ao VMWare e criar 2 novos discos, deixá-los sem formatação e agregá-los ao ASM.
Estou interessado nos dois últimos, veja que não existe partição, portanto vamos criar uma partição do disco inteiro para depois entregar o gerenciamento desses discos ao ASMLib, plugando discos na biblioteca. Vou criar dois volumes (VOL1 e VOL2), (*quando a instalação houver terminado, vou fazer testes deletando um dos discos no VMWare, isso simula um crash físico, ou seja, vamos testar o +ASM pra valer).
Com o fdisk, vamos criar uma partição por disco, toando o espaço todo e depois reboot.
Tudo pronto e certo para instalação do ASM com Oracle 10g.
Vou até o /mnt/xp, onde já estão as bibliotecas do ASMLib e vou instalar de lá os rpms. Tenho que instalar como root.
[root@yoda mnt]# cd xp
[root@yoda xp]# rpm -Uvh \
> oracleasm-2.6.9-34.ELsmp-2.0.1-1.i686.rpm \
> oracleasmlib-2.0.1-1.i386.rpm \
> oracleasm-support-2.0.1-1.i386.rpm
Preparing... ########################################### [100%]
1:oracleasm-support ########################################### [ 33%]
2:oracleasm-2.6.9-34.ELsm########################################### [ 67%]
3:oracleasmlib ########################################### [100%]
[root@yoda xp]#
Configurando a biblioteca.
[root@yoda xp]# /etc/init.d/oracleasm configure
Configuring the Oracle ASM library driver.
This will configure the on-boot properties of the Oracle ASM library
driver. The following questions will determine whether the driver is
loaded on boot and what permissions it will have. The current values
will be shown in brackets ('[]'). Hittingwithout typing an
answer will keep that current value. Ctrl-C will abort.
Default user to own the driver interface []: oracle
Default group to own the driver interface []: dba
Start Oracle ASM library driver on boot (y/n) [n]: y
Fix permissions of Oracle ASM disks on boot (y/n) [y]: y
Writing Oracle ASM library driver configuration: [ OK ]
Creating /dev/oracleasm mount point: [ OK ]
Loading module "oracleasm": [ OK ]
Mounting ASMlib driver filesystem: [ OK ]
Scanning system for ASM disks: [ OK ]
[root@yoda xp]#
Próximo passo é investigar quais serão os discos para serem criados no ASM, para isso vou usar o fdisk. No meu caso, eu deixei para plugar 2 discos depois da instalação por isso que no output abaixo, não encontramos os discos. Terei que ir ao VMWare e criar 2 novos discos, deixá-los sem formatação e agregá-los ao ASM.
[root@yoda ~]# fdisk -l
Disk /dev/sda: 4294 MB, 4294967296 bytes
255 heads, 63 sectors/track, 522 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 * 1 19 152586 83 Linux
/dev/sda2 20 522 4040347+ 8e Linux LVM
Disk /dev/sdb: 2147 MB, 2147483648 bytes
255 heads, 63 sectors/track, 261 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sdb1 * 1 261 2096451 82 Linux swap
Disk /dev/sdc: 4294 MB, 4294967296 bytes
255 heads, 63 sectors/track, 522 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sdc1 * 1 522 4192933+ 8e Linux LVM
Disk /dev/sdd: 4939 MB, 4939212288 bytes
255 heads, 63 sectors/track, 600 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk /dev/sdd doesn't contain a valid partition table
Disk /dev/sde: 4939 MB, 4939212288 bytes
255 heads, 63 sectors/track, 600 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk /dev/sde doesn't contain a valid partition table
Estou interessado nos dois últimos, veja que não existe partição, portanto vamos criar uma partição do disco inteiro para depois entregar o gerenciamento desses discos ao ASMLib, plugando discos na biblioteca. Vou criar dois volumes (VOL1 e VOL2), (*quando a instalação houver terminado, vou fazer testes deletando um dos discos no VMWare, isso simula um crash físico, ou seja, vamos testar o +ASM pra valer).
Com o fdisk, vamos criar uma partição por disco, toando o espaço todo e depois reboot.
[root@yoda ~]# fdisk /dev/sdd
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
Command (m for help): p
Disk /dev/sdd: 4939 MB, 4939212288 bytes
255 heads, 63 sectors/track, 600 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-600, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-600, default 600):
Using default value 600
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
[root@yoda ~]# fdisk /dev/sde
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
Command (m for help): p
Disk /dev/sde: 4939 MB, 4939212288 bytes
255 heads, 63 sectors/track, 600 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-600, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-600, default 600):
Using default value 600
Command (m for help): p
Disk /dev/sde: 4939 MB, 4939212288 bytes
255 heads, 63 sectors/track, 600 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sde1 1 600 4819468+ 83 Linux
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
Syncing disks.
[root@yoda ~]# shutdown -r 0
Criando os volumes.
[root@yoda ~]# /etc/init.d/oracleasm createdisk VOL1 /dev/sdd1
Marking disk "/dev/sdd1" as an ASM disk: [ OK ]
[root@yoda ~]# /etc/init.d/oracleasm createdisk VOL2 /dev/sde1
Marking disk "/dev/sde1" as an ASM disk: [ OK ]
[root@yoda ~]# /etc/init.d/oracleasm listdisks
VOL1
VOL2
Tudo pronto e certo para instalação do ASM com Oracle 10g.
Labels: how to