.comment-link {margin-left:.6em;}

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! :-)

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:


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
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) );

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.

Abaixo, a técnica: Vejo se consigo encontrar a posição onde começa e termina os numerais. Portanto:
XXX9999YYY
1234567890 = Incio,fim (4,7)

XX9999999YY
12345678901 = Inicio,fim (3,9)
Por 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.
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:


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.

[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 ('[]'). Hitting without 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:


This page is powered by Blogger. Isn't yours?