Archive for the ‘oracle’ Category

Como usar Case em Oracle

Tuesday, May 6th, 2008

(Postado originalmente no dia 23/04/07)

Pode acontecer que necessitemos devolver um texto ou valor dependendo dum dado duma coluna numa tabela Oracle.
Por exemplo:
Se temos uma tabela de nome Empleado_Salarios com os campos
Empleado, Salario
e com valores
Agustin, 20.000
Ignacio, 1.500
Nicolás, 10.000

E num “select” queremos em vez de mostrar os valores exatos e mostrar categorias, podemos usar a sentencia CASE de Oracle como mostra o seguinte exemplo.

Select Empleado,
CASE
when Salario < 5.000 then ‘Salario Bajo’
when Salario >= 5.000 and Salario < 15.000 then ‘Salario Medio’
else ‘Salario Alto’
END Categoria_Salario
from Empleados_Salarios;

A sentencia contem as palavras reservadas “when” para estabelecer as condições, “else” para o caso que não cumpra uma das condições when, e “CASE” e “END” que encerram a cláusula condicional, coloquei a palavra “Categoria_Salario” como alias duma coluna de categorias.

Outro exemplo simples poderia ser:
Tenho uma tabela de nome Stock com 3 campos:

Material char(20),
Entradas number(10),
Saidas number(10)

E quero saber os saldos positivos de Entradas - Saidas, e no caso que as Saidas sejam maiores que as Entradas, não quero mostrar o valor negativo, senão um valor 0.
Temos que ter em consideração os valores nulos que poderia ter de Entradas ou Saídas

O select seria o seguinte:

Select Material,Nvl(entradas,0) Entradas, Nvl(saidas,0) Saidas,
Case Nvl(entradas,0) - Nvl(saidas,0) > 0 then Nvl(entradas,0) - Nvl(saidas,0)
else 0
End Diferencia
from Stock;

Fabricio De los Santos
Gerência de Projetos -
Consultoria GeneXus -
ERP – Sistemas de Missão Crítica - Bancos de Dados.

Veja meus blogs em:
www.fabriciodelossantos.com

Error ORA-00957 GeneXus Oracle duplicate column name

Monday, May 5th, 2008

(Postado originalmente no dia 17/04/07)

Duplicate column name ou ORA-00957 com oracle, no meu caso Visual Basic, se produz basicamente por um erro comum que pode acontecer.

Se deve basicamente a que possivelmente no código tanto seja num New ou num When Duplicate se está fazendo referencia a um atributo 2 vezes por erro.

Exemplo:

New
CliCod=&CliCod
CliNom=&CliNom
CliEnd=&CliEnd
CliEnd=&Endereco
EndNew

Também pode acontecer num When duplicate não documentado neste exemplo.
É um erro simples de cometer geralmente quando se copiam códigos de um objeto para outro.

Fabricio De los Santos
Gerência de Projetos -
Consultoria GeneXus -
ERP – Sistemas de Missão Crítica - Bancos de Dados.

Veja meus blogs em:
www.fabriciodelossantos.com

Explain Plan para Otimizar consultas sql oracle

Friday, May 2nd, 2008

(Postado originalmente no dia 04/10/06)

Quando o resultado de uma consulta demora muito e queremos saber o porquê, podemos ver um detalhe do que a consulta está fazendo.
Passos a seguir usando o sqlplus:
1)
alter session set sql_trace=true;

2)
explain plan for select …….

3)
select operation ||’ ‘||options||’ ‘||object_name from plan_table
connect by prior id=parent_id
start with id=1;

Informação obtida de: ADP

Fabricio De los Santos
Gerência de Projetos -
Consultoria GeneXus -
ERP – Sistemas de Missão Crítica - Bancos de Dados.

Veja meus blogs em:
www.fabriciodelossantos.com

XDB connect to localhost

Friday, May 2nd, 2008

(Postado originalmente no dia 20/09/06)

É um erro que aconteceu algumas vezes quando instalando Tomcat numa PC que tem Oracle। Este erro é porque está rodando um XDB Server Oracle escutando na porta 8080, mesma porta que usa Tomcat por default।

As opções que temos são:

  1. Mudar a porta por default do Tomcat.
  2. Des-Habilitar a porta do XDB em Oracle. Para isso abrimos o enterprise manager, expandimos a base de dados que está instalada local nesse PC e no tag “configuração” trocamos o HTTP port por 0

Nota Importante: Tem que se conectar como sysdba ao banco de dados, caso contrario não será possível efetuar a operação.

A informação foi obtida procurando no site: http://www.fmepedia.com

Fabricio De los Santos
Gerência de Projetos -
Consultoria GeneXus -
ERP – Sistemas de Missão Crítica - Bancos de Dados.

Veja meus blogs em:
www.fabriciodelossantos.com

core dump AIX 4.3.2 dsmc / ora:01017 - 01034

Sunday, April 20th, 2008

(Postado originalmente no dia 04/10/06)

Tentando rodar processos C gerados com Genexus, obtive um erro com o seguinte texto:
PCSS/SPI2 FLDS/ademonc SIG/11 FLDS/__modfini VALU/14 FLDS/exit

Achamos que o sistema, está gerando um coredump.
Provavelmente o problema seja que a password do usuário que executa os processos este errada, ou o arquivo de onde pega a password seja impossível de ler por falta de permissão ou por estar corrompido.

Exemplo de linha de arquivo de coredump:
ÀZ M’Ð ÿÿÿÿÿïp y•h ÿÿÿÿÿïp(BHB L ÿÿÿÿÿóP KM ÿT ” LÌ@ F8 ÷ ÷ õ0 üORA-01017: invalid username/password;

A solução é colocar o arquivo correto o a password correta dependendo do problema achado.

Achei a solução baseandome na documentação da seguinte URL: Mail Archive

Procurando por as seguintes palavras em Google.

Trace/BPT trap(coredump)
core dump AIX 4.3.2 dsmc

Fabricio De los Santos
Gerência de Projetos -
Consultoria GeneXus -
ERP – Sistemas de Missão Crítica - Bancos de Dados.

Veja meus blogs em:
www.fabriciodelossantos.com

Error ORA-01407 cannot update to null GeneXus Oracle

Sunday, April 20th, 2008

(Postado originalmente 25/04/07)

Este problema basicamente indica que está intentando fazer um update em uma tabela com um valor nulo, quando a coluna não permite isso.

As opções são modificar a fonte do programa ou a definição da transação GeneXus.
Se você verificou a fonte do programa, e acha que pode fazer o update a um valor nulo, e também verificou em GeneXus e está correta a definição, allownull=Yes, pode ter acontecido por algum motivo alguém mudou na mão no banco de dados a definição dessa coluna em particular.
Para verificar esta última possibilidade, faça um describe da tabela.
Verifique a coluna que indica o erro se está permitindo nulos ou não.

No caso que tenha sido mudada, corrija usando a seguinte sentencia SQL:

ALTER TABLE Nombre_de_Tabla MODIFY Nombre_de_Columna NULL;

Fabricio De los Santos
Gerência de Projetos -
Consultoria GeneXus -
ERP – Sistemas de Missão Crítica - Bancos de Dados.

Veja meus blogs em:
www.fabriciodelossantos.com

Que permisos de Oracle son necesarios para GeneXus?

Wednesday, December 26th, 2007

Desde que trabajo con GeneXus, en la mayoría de las empresas que estuve, he visto dar el rol de DBA al usuario que fuera a conectarse a la base de datos.

También he visto excepciones, que comentaré más adelante, pero generalmente, el mismo usuario que usamos para crear las tablas, es el usuario que también ejecuta la aplicación.

Esta es la forma más simple, rápida y con menos mantenimiento para trabajar, pero no la más correcta.

El problema es que hace muchos años, no existían tantos DBAs ORACLE. Entonces el choque de fuerzas entre los implantadores de sistemas GeneXus y los DBAs no era tan habitual, en muchas empresas no existían DBAs y simplemente el usuario que usábamos en GeneXus era el todo poderoso DBA.

Con el paso del tiempo la cosa se fue complicando, porque el usuario de ORACLE DBA tiene permisos más allá de los necesarios y podía acceder a otros esquemas del banco de datos, cuando generalmente era una instancia de base para todos los sistemas de la empresa, que corrían bajo esquemas distintos. Esto entre otras atribuciones peligrosas que tiene el usuario ORACLE DBA, dejaba a los DBAs humanos de pelos de punta.

Hasta la versión 9i de ORACLE, asociando los roles de CONNECT y RESOURCE, y dándole permisos ilimitados para TABLESPACE al usuario ya era suficiente, y digamos estábamos mejor que dar el ROL de DBA a nuestro usuario.

El problema es que a partir de la versión 10g de ORACLE, fueron sacados algunos privilegios del ROL CONNECT.
Estos fueron:
CREATE SYNONYM
CREATE VIEW.

Sumado a esto en la versión 9i de ORACLE, se repetían los siguientes privilegios entre CONNECT y RESOURCE.
Estos eran:
CREATE CLUSTER
CREATE SEQUENCE
CREATE TABLE

Como conclusión, si hoy usamos ORACLE 10g tenemos que estar tomando un privilegio de aquí, otro de allá, para crear nuestro usuario ORACLE, para poder ejecutar con GENEXUS, entonces la vida se hace un poco más complicada.

Para esto, la solución es crearnos nuestro propio script de ROL Y PROFILE y asignarle a nuestro usuarios este ROL y PROFILE.

A continuación anexo los scripts de las atribuciones mínimas necesarias para crear, reorganizar tablas, usar el sistema con nuestro usuario GENEXUS. Existen algunos privilegios comentados con (*) que indican que son opcionales, están colocados allí porque si debemos pedirle a un DBA oficial que nos cree un usuario, es bueno pedirle estos privilegios para cuando necesitamos conectarnos con sqlplus para ver algunos datos de tablas, crear alguna view para ser usada con DataViews desde GeneXus, etc.

Crear un rol

CREATE ROLE NUESTROROL NOT IDENTIFIED;

– Privilegios tomados del Rol CONNECT
GRANT CREATE SESSION TO NUESTROROL;
GRANT ALTER SESSION TO NUESTROROL; — (*)
GRANT CREATE DATABASE LINK TO NUESTROROL; — (*)

– Privilegios tomados del Rol RESOURCE
GRANT CREATE SEQUENCE TO NUESTROROL;
GRANT CREATE TRIGGER TO NUESTROROL; — (*)
GRANT CREATE PROCEDURE TO NUESTROROL; — (*)
GRANT CREATE TABLE TO NUESTROROL;

– Otros Privilegios
– (en versiones anteriores a ORACLE 10 estos privilegios estaban en CONNECT)
GRANT CREATE VIEW TO NUESTROROL; — (*)
GRANT CREATE SYNONYM TO NUESTROROL; — (*)

– Privilegios de sistema
– (permite ver views de diccionario)
GRANT SELECT ANY DICTIONARY TO NUESTROROL; — (*)

Crear un perfil

CREATE PROFILE NUESTROPERFIL LIMIT
IDLE_TIME 120
– (para no dejar que nuestros usuarios dejen el sistema abierto sin usarlo por más de 2 horas)
SESSIONS_PER_USER 50;
– (para no permitir más de 50 sesiones en simultáneo)

Este perfil con estos valores es opcional, en caso de no necesitar controlar nada de esto, podemos usar el perfil DEFAULT de ORACLE, o por el contrario si precisamos diferenciar procesador y o memoria entre otros recursos de ORACLE para una sesión, se puede entrar mas en detalles a la hora de crear un PROFILE.

Por default la instancia de base de datos no está habilitada para restringir recursos del perfil.
Para que nuestro perfil funcione debemos pedirle al DBA que nos habilite este parámetro, o si tenemos nosotros permisos de system podemos hacer esta modificación con el siguiente comando:

ALTER SYSTEM SET RESOURCE_LIMIT=TRUE;

Luego debemos bajar y subir nuevamente la base de datos para que comenzar con este parámetro activo.

Ahora si, finalmente creamos el usuario:

Crear un usuario

CREATE USER NUESTROUSUARIO
IDENTIFIED BY NUESTROPASSWORD
DEFAULT TABLESPACE USERS
– (es recomendable tener nuestro tablespace definido)
TEMPORARY TABLESPACE TEMP
– (es recomendable tener nuestro tablespace definido)
PROFILE NUESTROPERFIL
ACCOUNT UNLOCK;
GRANT UNLIMITED TABLESPACE TO NUESTROUSUARIO;
GRANT NUESTROROL TO NUESTROUSUARIO;

Cabe aclarar un pequeño pero no menos importante detalle, referente al privilegio UNLIMITED TABLESPACE, tanto en versiones anteriores, como en la versión de ORACLE 10g, cuando asignamos el ROL RESOURCE, ORACLE también asigna este privilegio al usuario, cosa que no sucede cuando creamos nuestro propio ROL.
Si quisiéramos intentar asignar este privilegio a nuestro rol, nos daria el siguiente error:

ORA-01931
Cannot grant string to a role.
Cause: UNLIMITED TABLESPACE,\nREFERENCES, INDEX, SYSDBA or SYSOPER privilege cannot be granted to a\nrole.

Por tal motivo el GRANT debemos hacerlo a la hora de crear el usuario, como muestra el script anterior.

Espero que este resumen le haya sido útil.

Fabricio De los Santos
Gerencia de Proyectos -
Consultoría GeneXus -
ERP – Sistemas de Misión Crítica - Bases de Datos.

Vea mis blogs en:
www.fabriciodelossantos.com

Como desinstalar oracle 9

Monday, December 17th, 2007

Como desinstalar oracle completamente, borrando entradas en el registro de windows.

Luego de probar la versión 10g de oracle me decidí a desinstalar Oracle 9.2 de mi máquina, y me encontré con algunos detalles, que no pude apagar definitivamente, como carpetas de oracle y entradas de oracle en los servicios de windows.
Intenté instalar el oracle 10 por arriba pero me encontré con otros problemas a la hora de ejecutar.
En fin, terminé creando una guia que comparto aqui con un paso a paso para desinstalar oracle 9 por completo.

Paso a paso

- Verificar si se tiene odbcs asociados y eliminarlos ya que después quedan corruptos y da otro dolor de cabeza desinstalarlos (aunque también podemos después crear uno nuevo con el mismo nombre y ahí podemos apagarlo, pero lo más prolijo sería eliminar el odbc asociado antes de desinstalar oracle)
- Ejecutar el universal installer
- Borrar todos los homes que aparezcan
- Borrar la variable de ambiente ORAHOME
- Borrar de la variable de ambiente PATH todas las referencias a oracle (panel de control / sistema / avanzado / variables de ambiente)
- Borrar del registro toda referencia a oracle (ejecutar regedit buscar carpeta oracle y borrar)
- Reiniciar el pc
- Borrar la carpeta oracle debajo de c:\

En mi caso en particular como tenia la base de datos instalada local el instalador/desinstalador no me borró los servicios OracleHome92TnsListener y OracleServiceMiMaquina.

Tenemos dos formas de borrar estos servicios de windows

1) sc delete OracleHome92TnsListener

Entramos en el panel de control / servicios y ya no está mas.

2) Ejecutando regedit
Borramos la cadena correspondiente a OracleServiceMiMaquina en:

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services

Esta segunda opción lo que tiene de diferente es que para ver si el servicio desapareció del panel de control / servicios, hay que reiniciar el pc

Si se usa la primera opción no es necesario reiniciar el pc.

Fabricio De los Santos
Gerencia de Proyectos -
Consultoría GeneXus -
ERP – Sistemas de Misión Crítica - Bases de Datos.

Vea mis blogs en:
www.fabriciodelossantos.com

Función Replace de Oracle

Thursday, October 4th, 2007

Siempre que parece que está todo controlado, aparece algo que te hace tambalear.

Hicimos una carga masiva de datos en una tabla mediante la importación de un archivo.
Hasta ahí todo normal. El problema era que el único campo de la clave venía con algunas “/”.
En particular este caso el sistema está generado con GeneXus 9 y Visual Basic.
Ahora bien, no me pregunten por que, estuvimos algún tiempo intentando resolver el problema, pero en un workpanel que sería el “Trabajar con” nos aparecían los datos con “/”.
Pero a la hora de entrar en modo update en esa Trn, el sistema le quitaba la barra y solo nos aparecía el código sin barra y obviamente no encontraba el registro.
El atributo no tenía ninguna propiedad extraña, picture, ni nada que se le parezca.
Intentamos reproducir el problema con otra trn, creada con otros campos pero de las mismas características y nada.
Cuando los tests parecía llevar horas y no teníamos ese tiempo decidimos, sacarle la “/” al código (dejando para algún día ver el por que del problema).

Ahí comencé a inventar algo a ver que podía hacer para sacar esa barra, y la verdad, la solución tomó 2 minutos.

Usamos la función Replace de Oracle

replace( s1, s2, [ s3 ] )

s1 es el string que quiero buscar, en mi caso el campo
s2 es el string que quiero remplazar en mi caso “/”
s3 parámetro opcional cuando quiero sustituir uno por otro, yo podría haber querido sustituirlo por un “-” pero no era necesario.

Solución:

UPDATE mitabla SET micampo=REPLACE(micampo,’/')

Me encontré con algunas sorpresas, de unique constraint violated, pero ahí es porque el usuario como no encontraba con “/” cadastró el mismo código en el sistema, pero sin “/”, entonces antes tuve que quitar las constraints, ver los registros duplicados y eliminar uno de ellos para luego aplicar las constraints nuevamente de primary key.

Si les llega a pasar tienen que hacer:

ALTER TABLE mitabla DROP CONSTRAINT nombre_constraint

ALTER TABLE mitabla ADD (
PRIMARY KEY (micampo)
USING INDEX
TABLESPACE USERS);

Fabricio De los Santos
Gerencia de Proyectos -
Consultoría GeneXus -
ERP – Sistemas de Misión Crítica - Bases de Datos.

Vea mis blogs en:
www.fabriciodelossantos.com

Obtener 2 últimos registros concatenados con SQL Oracle usando rownum

Saturday, September 8th, 2007

El otro día, un amigo me preguntó como podía hacer para obtener los 2 últimos registros (con mayor fecha) ingresados en una tabla, pero concatenados.
Realmente estaba con la cabeza en otra cosa, pero generalmente me intereso por ese tipo de “rompecabezas” SQL y bueno me pareció interesante publicarlo.

Ejemplo:

Tenemos una tabla llamada “Entradas”

La cual tiene una clave que llamaremos “Codigo”, un campo “Fecha” que es el criterio de ordenación, y un campo “Otros” que simula el resto de los campos de la tabla.

Para filtrar los 2 últimos registros pensé en usar “rownum”, pero el problema era que los últimos registros ingresados, no coincidían con los últimos correspondientes a las fechas digitadas.

Ejemplo:

Haciendo un select ordenado por fecha descendiente mis últimos 2 registros son los de código 31 y 28

Select Codigo,Fecha,Otros from Entradas order by Fecha Desc

31, 07/09/2007, xxx
28, 06/09/2007, yyy
29, 05/09/2007, zzz
30, 04/09/2007, uuu

Pero al utilizar el rownum, como el mismo es parte de la condición, antes del order by simplemente me devuelve los 2 últimos registros ingresados.

Select Codigo,Fecha,Otros where rownum <= 2 order by Fecha Desc

31, 07/09/2007, xxx 30, 04/09/2007, uuu

Solución para obtener los 2 últimos registros ordenados por fecha descendente: Hacer un select ordenado por fecha descendente y a esto aplicar la condición de rownum

select * from

(select Codigo,Fecha,Otros from Entradas order by Fecha Desc)

where rownum <= 2

31, 07/09/2007, xxx 28, 06/09/2007, yyy

Ahora bien, para obtener los 2 últimos registros concatenados, como puedo hacer?

Bien, la solución es aplicar la misma lógica pero para obtener 1 solo registro y luego al resultado de esto, aplicarlo a un producto cartesiando, mostrando aquellos registros en los cuales no se aplique el producto cartesiano entre si mismo।

Ejemplo:

select * from
(select * from
(select Codigo,Fecha,Otros from Entradas order by Fecha Desc)
where rownum = 1) a,
(select * from
(select Codigo,Fecha,Otros from Entradas order by Fecha Desc)
where rownum <= 2) b
where a.Codigob.Codigo

31, 07/09/2007, xxx,28, 06/09/2007, yyy

Espero sea útil para aquellos que algún día se encuentren con este problema.
Personalmente, no se para que mi amigo quería este resultado, pero el desafío fue interesante.

Fabricio De los Santos
Gerencia de Proyectos -
Consultoría GeneXus -
ERP – Sistemas de Misión Crítica - Bases de Datos.

Vea mis blogs en:
www.fabriciodelossantos.com