viernes, 1 de abril de 2011

Oracle 11gR2 XE Beta is now available


Para muchas personas esta noticia pasara desapercibida, pero para nosotros los que desarrollamos, muchas veces necesitamos hacer pruebas que no dependan  de qu nuestro dba este haciendo mantenimientos o respaldos o el cliente se este quejando de que tus pruebas alentan su sistema. y es por eso que hoy ya esta disponible la nueva versión de la siempre confiable XE ,
Disponible para su descarga aqui Oracle XE 11G 
En el portal de Oracle.

Que lo disfruten!!!

Project Status Inquiry (PSI) Consulta de estado de Proyecto.

Proyectos : es el modulo encargado del manejo de costos, ingresos, recursos , tareas, etc  de un proyecto.

Brinda información detallada sobre el estado del mismo por medio de una pantalla muy practica donde te permite dar información de una manera tan flexible que asusta, y digo asusta por que con los conocimientos adecuados de la estructura del modulo de Proyectos y conocimientos de el lenguaje PL/SQL le pueden ahorrar tanto trabajo al usuario de una manera casi ilimitada. La pantalla de la que hablo maravillas es una pantalla que en algún momento mi amigo Jose de Jesús Martinez Cañas, tuvo a bien explicarme el funcionamiento de la pantalla PSI.

El PSI tiene una peculiaridad que  pocas pantallas de la aplicación tienen, y esto es : Es una pantalla que pueden modificarse la forma en la que se entregan los  datos de prácticamente todas las columnas, esto quiere decir, que si uno desea puede reconstruir todos los datos que te presenta la pantalla, las etiquetas, promedios, sumatorias, minería de datos a otros módulos que tengan que ver con el proyecto o hasta lo que no tenga que ver con el proyecto se puede pintar en esta pantalla.

Las pantallas de configuración de esta pantalla nos dejan muy claro a los desarrolladores que la persona que hizo esta pantalla seguramente le cambiaron la definición de lo que querían que se viera en esta pantalla , que el decidió dejarle a los funcionales la tarea de definir que pintara la pantalla con la información disponible del modulo.

ejemplo:
Flexibilidad en cada columna.

La etiquetas del reporte también son edita bles desde esta pantalla 

Son 33 columnas para el nivel Proyecto

Y esto se puede configurar tanto para el nivel proyecto como para tarea y Recursos.
 Ahora como es tan mágico esta pantalla, como permite tal cosa, acaso las pantallas del psi se construyen en tiempo de ejecución?

No es magia ni algo remotamente parecido, lo que sucede es que genera vistas en la base de datos cuando uno le da generar visualización, vistas que como su nombre lo dicen son genéricas.

PA_STATUS_PROJ_GENERIC_V

PA_STATUS_TASK_GENERIC_V

PA_STATUS_RSRC_GENERIC_V

Estas 3 vistas contienen permiten extraer los datos como los solicito el usuario en la configuración en cada uno de los niveles del reporte, sin embargo cuando uno trata de ejecutarlas en la base de datos estas no regresan nada. como inicializar las vistas del PSI para que nos regresen valores es el  reto.

Para que no se quiebren la cabeza recordemos como funciona la aplicación.

La seguridad desde R11 y ahora en r12 se maneja por medio de los perfiles de las responsabilidades y para poder emular lo que hacen las pantallas de la aplicación para restringir el acceso a los usuarios se tienen que ejecutar siempre las funciones que inicializan los valores de la responsabilidad del usuario, y a partir de la R12 se implemento la seguridad por medio de los perfiles por lo que ahora se agregan las funciones MO.
BEGIN
 FND_GLOBAL.APPS_INITIALIZE(1117,50719,275);
/*FND_GLOBAL.APPS_INITIALIZE(user_id,resp_id,resp_appl_id);*/
MO_GLOBAL.init('PA');
 /*MO_GLOBAL.init(application short name);*/
pa_budget_utils.set_entry_level_code('A');
pa_security.SET_VALUE('ALLOW_QUERY','Y');

APPS.PA_STATUS.pa_status_driver(38,NULL
,NULL,NULL,'AC','AR'
,TRUNC(SYSDATE,'MM'),LAST_DAY(SYSDATE),1);
/*PROCEDURE pa_status_driver (
  x_project_id =>Id Proyecto  
  , x_task_id => Id tarea
  , x_resource_list_id => Id lista de recursos
  , x_resource_list_member_id =>  id miembro
  , x_cost_budget_code  =>codigo del tipo de presuspuesto de costos
  , x_rev_budget_code IN => codigo del tipo de presupuesto de Ingresos
  , x_start_date IN DATE =>Fecha inicial de periodo  a analizar
  , x_end_date IN DATE =>Fecha final de periodo  a finalizar
  , x_factor IN NUMBER=>Factor entre el que se dividirán las operaciones
);
*/ 

END;
 /

 Este procedimiento anónimo estaría inicializando las variables de ambiente suficientes para que te permita realizar consultas sobre las vistas estándar del proyecto y podemos realizar toda la minería de datos que queramos.

Espero les sea útil.

jueves, 31 de marzo de 2011

ORA-01403: no data found,ORA-01403: no data found ,ORA-23494: too many rows and Select Into

ORA-01403: no data found ,ORA-23494: too many rows for destination and Select Into
ORA-01403: no data found
Cause: In a host language program, all records have been fetched. The return code from the fetch was +4, indicating that all records have been returned from the SQL query.

Action: Terminate processing for the SELECT statement.

ORA-23494: too many rows for destination "string"
Causa: The specified destination has too many rows
Acción: Ensure the specified destination has at most two valid rows before retrying this operation.

Esto es lo que encuentras al buscar este error.

no data found, Como olvidar este error, y aqui te presento a uno de los principales culpables:

Select datos
Into variables
from tabla

Dentro de las mas grandes bendiciones/maldiciones que existen en pl/sql esta esta bendita/maldita sentencia, porque se preguntaran?, bueno pues resulta de que cuando te enseñan esta sentencia, debería venir de la mano con un manual de por que deberías evitar utilizarla, a que me refiero:

Cuando tu utilizas la sentencia select into , significa que de manera directa deseamos obtener información de la base y que nos la deposite dentro de variables en nuestro código, que utilizado correctamente nos puede ahorrar algunas lineas de código dentro de nuestros procedimientos, sin embargo si no estas absoluta y completamente seguros de que tu consulta siempre regresara uno y solo un registro, en caso de que no estés seguro de lo anterior, tu proceso debería estar preparado para lo peor.

es decir deberia por lo menos agregar el siguiente codigo:

begin
Select datos
Into variables
from tabla
exceptions
when no_data_found then
/*lo que quieras hacer cuando no encuentre datos*/
when too_many_rows
/*lo que quieras hacer cuando encuentre mas de un registro */
end;



Espero este pequeño ejemplo sea útil.

miércoles, 30 de marzo de 2011

Order by en columnas de tipo caracter

Normalmente cuando nos encontramos con reportes que entregan una columna de numero de documento , el usuario solicitara que la información se le entregue ordenada con respecto a este campo , pero que pasa cuando esta columna incluye datos tanto alfanuméricos?

a pues si se ordenan puede darte cosas como estas


10000000001
111011
1111
A1201


cual es la solución mas sencilla ,

agregar en las seccion del order by


select (datos)
 from tabla
order by lpad(columna,longitud columna,'0')

 Un ejemplo con la tabla de transacciones de la ebs

select trx_number
  from ra_customer_trx_all
order  by  lpad(trx_number,50,'0')

si esta tabla tuviera solo los datos de arriba los presentaría asi

1111
A1201
111011
10000000001

 Espero que les sea útil , felices reportes.

jueves, 3 de marzo de 2011

ALTER SEQUENCE NEXTVAL ?

Algunas veces cuando realice un proceso que servía para generar la generación de un archivo me solicitaron que le colocara un numero como folio al archivo. Y esto fue muy sencillo solo me base en una secuencia de Oracle. Todo funciono muy bien hasta que llego el momento en el que me dijeron "Necesitamos regenerar la secuencia por que lanzamos muchos archivos mal y no podemos gastar esos folios así por que si".





A pues resulta que no hay una manera directa de colocarle el siguiente valor a una secuencia, y esto se puede conseguir de dos maneras (las que conozco):







  • Drop Sequence: Simplemente hacer drop al objecto de base de datos y colocar en la construción del objeto la sentencia "start with " y el numero en el que les soliciten iniciar:


drop sequence my_seq;



create sequence my_seq



start with 1234



nocache



order;



/





  • Manera comoda, buscando por ahí se encontraran con que no existe un comando alter sequence nextval, pero hay una manera de hacerlo por medio de jugar con lo que nos brinda Oracle: ALTER SEQUENCE MINVAL, ALTER SEQUENCE INCREMENT BY.


EL siguiente procedimiento de pl se encarga de realizar el truco mas cómodamente :


CREATE OR REPLACE PROCEDURE XXX_RESET_SEQUENCE (

PS_SEQ_NAME IN VARCHAR2, P_STARTVALUE IN NUMBER) AS

LN_VAL NUMBER (30);

MIN_VAL NUMBER (30);

LS_BUFF VARCHAR2(25);

LS_CYCLE_FLAG VARCHAR2(25);

BEGIN

SELECT CYCLE_FLAG

INTO LS_CYCLE_FLAG FROM USER_SEQUENCES

WHERE SEQUENCE_NAME =PS_SEQ_NAME;

EXECUTE IMMEDIATE 'SELECT ' PS_SEQ_NAME '.NEXTVAL FROM dual'INTO LN_VAL;

LN_VAL := -1*(LN_VAL - P_STARTVALUE 1);

EXECUTE IMMEDIATE 'ALTER SEQUENCE ' PS_SEQ_NAME' MINVALUE 0';

LS_BUFF := ' INCREMENT BY ';

EXECUTE IMMEDIATE 'ALTER SEQUENCE ' PS_SEQ_NAME LS_BUFF LN_VAL;

EXECUTE IMMEDIATE 'SELECT ' PS_SEQ_NAME '.NEXTVAL FROM dual'

INTO LN_VAL;

EXECUTE IMMEDIATE 'ALTER SEQUENCE ' PS_SEQ_NAME ' INCREMENT BY 1';

END XXX_RESET_SEQUENCE;

/

Y de la siguiente manera se cambiaria el valor de la secuencia;

BEGIN

XXX_RESET_SEQUENCE('MY_SEQ',2);

END;

/

Ventajas y Desventajas

Drop:

Ventaja puede iniciar desde 0(cero), es directo.

Desventaja, al hacer drop del objeto se invalidan todas las dependencias de este.

Procedimiento:

Desventaja: No me permitió iniciar en 0(cero) el valor más bajo al que llego es 1.

Ventaja: No requiere recompilación de dependencias.

Espero que les sea útil.








lunes, 21 de febrero de 2011

APEX PLUGINS


Navegando por Internet de lo que uno se entera y hoy me toco toparme con los Plug-Ins para APEX, Que es esto?

Pues muchas veces en vez de desarrollar una complicada herramienta para nuestro sistema, debemos darnos la oportunidad de revisar si lo que queremos hacer ya lo hizo alguien mas y es ahí donde entran los plugins que oracle ya a liberado muchas herramientas para que tus aplicaciones sean aun mas completas con un par de clics extra, por ejemplo:

Agregarle el Boton Me gusta de Facebook , cambiar tu estatus en tweeter o agregar la funcionalidad del captcha de google a tu aplicación.

En el siguiente link encontraran una lista de los Plug-Ins que Oracle recomienda, así como los links a el repositorio de Plug-Ins:

Oracle APEX Plug-Ins

Sitio Oficial de Plug-Ins APEX

Espero les sean de utilidad.


domingo, 20 de febrero de 2011

Oracle, Where is the bug ?

Existen ocasiones donde nos encontramos con bugs dentro de nuestros programas y no podemos mostrar la salida de nuestro programa para ir dándonos una idea de donde ocurre el error, para ese tipo de situaciones Oracle nos brinda herramientas como el trace y a este aplicarle el famoso tkprof sin embargo no siempre tenemos a la mano el acceso al servidor por shell o simplemente no tenemos a un dba de cabecera ( yo sigo sin tener el mio y eso que en este proyecto hay 2 ) bueno pues para estas ocaciones lo que yo uso normalmente es un procedimiento que escribe en una tabla y me va dejando una pista te lo que ocurre en mi código.

El script de instalación es el siguiente:

CREATE SEQUENCE XXX_DEBUG_S;

CREATE TABLE "XXX_DEBUG_TAB"

( "ID" NUMBER,

"IDENTIFIER" VARCHAR2(50),

"CHAR_TIME" VARCHAR2(50),

"TEXT" VARCHAR2(4000) );

CREATE OR REPLACE PROCEDURE "XXX_DEBUG_TXT" (pIdentifier In Varchar2, pText In Varchar2) Is pragma autonomous_transaction;

Begin Insert into XXX_debug_tab

(id, identifier, char_time, text)

values

(XXX_DEBUG_S.nextval, pIdentifier, to_char(SYSTIMESTAMP, 'DD/MM/YYYY HH24:MI:SS FF6'), pText);

commit;

End; /


Ahora y esto para que nos sirve, pues es muy sencillo el procedimiento de arriba se encarga de insertar a una tabla cada ves que lo llaman, algo asi:

begin

XXX_DEBUG_TXT('DEPURA','AQUI ESTOY:'||VAR1);

end;


Que tiene esto de practico? Pues que lo puedes meter en cualquier parte de tu código y no altera tu procesamiento natural, ya que al utilizar la sentencia "pragma autonomous_transaction" este procedimiento se ejecuta dentro de una sesión diferente y su commit no afecta tu programa natural permitiendo que tu transacción continúe como si nada hubiese pasado y tu puedes seguir monitoreando desde otra sesión.

Y si ocurre algun error tu puedes ir guardando tus variables o datos que te puedan ayudar a identificar los bugs de tus programas o aquellos programas que te toque revisar.

Espero les sea útil y felices compilaciones ¡¡¡