Este blog lo estoy iniciando para publicar lo que aprendo día a día de tecnología. Y así facilitar la vida a más compatriotas que comienzan a emprender viajes por el mundo de la tecnología.
viernes, 16 de octubre de 2015
FORMS R12 PROGRESS BAR THE DEFINITIVE GUIDE
adding a progress bar
so where is the code:
APP_WINDOW.PROGRESS( 0,'First Message..... ');
synchronize
/*Long time operation*/
APP_WINDOW.PROGRESS(.1,'Second Message..... ');
synchronize;/*Long time operation*/
APP_WINDOW.PROGRESS(.3,'Third Message..... ');
synchronize
/*Long time operation*/
APP_WINDOW.PROGRESS(.4,'YOU GET IT .... ');/*Long time operation*/
synchronize;
APP_WINDOW.PROGRESS(100);
Has simple has that well why write this article if this is on the documentation basically because on the documentation talks about closing when the parameter is greater than 99% but they didn't tell you that they move the percentage in a value between 0 and 1 so 50% equal to .5 .
So have fun.
domingo, 23 de agosto de 2015
Utilizando Variables alenta mi TOAD - Using bind variables in the Toad editor causes delays.
La Solución:
Cierra Toad y deja de usarlo :( . . . Naaaaah solo bromeo.
Ve a tu folder de Usuario:
en mi caso:
C:\Users\Javier\AppData\Roaming\Quest Software\Toad for Oracle\10.0\User Files
Una vez ahí
Renombra(Solo si de verdad pero de verdad necesitas utilizar esas variables despues) / Borra el archivo variables.dat.
Inicia Toad de nuevo.
Espero que te ayude.
For all of those who use toad, sooner or later may start having issues with the performance of the bind variables and it's thanks to the super ability of your tool to remember the settings of your bind variables, and what does it means. Basically toad generates a file where it saves all those setting so it can remember when you call that same variable again and again. but if has a price if you run a large script with many variables it starts appending to that file.
The solution :
Close Toad and stop using it :( . . . just kidding.
go to your user folder:
Mine by example
C:\Users\Javier\AppData\Roaming\Quest Software\Toad for Oracle\10.0\User Files
Once there
rename(If you really but seriously really need those values for later)/ remove the variables.dat file.
Start Toad Again.
Hope it helps.
jueves, 7 de agosto de 2014
Generating Records from DUAL
A trick that a friend told me is,
Just use Dual,
select *
from dual
connect by level <=:p_number_of_rows;
With this you have all the rows that you could need whithout a single insert.
Hope it helps.
miércoles, 6 de agosto de 2014
Mutli Table Inserts
Normally You will create something like this
INSERT into TABLE A
Values ..
Query
INSERT into TABLEB
Values ..
Query
INSERT into TABLEC
Values ..
Query
For those cases oracle created the Multi Table Insert which loks like this:
INSERT
WHEN ... THEN
INTO ... VALUES ...
WHEN ... THEN
INTO ... VALUES ...
subquery;
Aa simple sample will be if you want to insert the firsr 5 row's on the table A, then on the next 2 records on table b and then everithing else on other table, the sample will look like this:
I created this 3 tables:
create table table_demo_1
(dat_1 varchar2(10),
num_2 number );
create table table_demo_2
(dat_1 varchar2(10),
num_2 number );
create table table_demo_3
(dat_1 varchar2(10),
num_2 number );
And onse done that I execute the sentence has follows
INSERT
WHEN ROW_NUM<=5 THEN
INTO table_demo_1 (dat_1,NUM_2) VALUES ('A',ROW_NUM)
WHEN ROW_NUM BETWEEN 6 AND 7 THEN
INTO table_demo_2 (dat_1,NUM_2) VALUES ('B',ROW_NUM)
ELSE
INTO table_demo_3 (dat_1,NUM_2) VALUES ('C',ROW_NUM)
SELECT DUMMY, ROWNUM ROW_NUM
FROM dual
CONNECT BY LEVEL<=10 ;
Easy has you can see.
miércoles, 23 de julio de 2014
Date tricks on SQL
Well the truth is that must of the people never reads a manual because . . . is bigger than the bible.
So here is a simple explanation of the Date Datatype in Oracle Sql. First of all a date data type only stores date + time but only with a precision of seconds if you need to record fractional second then you need to use a different data type.
In almost all the languages the dates can be converted from and to strings directly. well here is not the exception, but you need to be careful because it always depends on the setup of the database.
this 3 parameters:
nls_date_format <---- br="" date="" format="">nls_language <---- br="" database="" language="" of="" the="">nls_territory <--- br="" database="" of="" territory="" the="">You can get the values from them with the following query:--->---->---->
select *
from v$parameter
where name in ('nls_date_format'
,'nls_language'
,'nls_territory');
By default the language and territory are american and america , and the date format is DD-MON-RR, wich means '12-JAN-14' is a valid date that represents 12 January of 2014, that was easy right but . . .
What happens when your source of data has a diferent format, for example
select '07-12-1985' from dual
to make this a date
select to_date('07-12-1985','DD-MM-RRRR') from dua.
If you are bored here begin the tricks
Imagine that somen one ask you to generate a range of dates,
1,2. . . . . 30 jan 2014
how do i this?
Select start_date+level-1 calc_date
from (select to_date('01-01-2014', 'dd-mm-rrrr') start_date,
to_date('31-01-2014', 'dd-mm-rrrr') end_date
from dual) connect by level<=end_date-start_date+1
How to get the first day:
select trunc(to_date('31-01-2014', 'dd-mm-rrrr'),'mm') fisrt_day
from dual;
How to get the last day:
select last_day(to_date('31-01-2014', 'dd-mm-rrrr')) last_day
from dual;
How to add days 12 days:
select to_date('31-01-2014', 'dd-mm-rrrr') + 12 add_days
from dual;
How to add 12 months:
select add_months(to_date('31-01-2014', 'dd-mm-rrrr'),12) add_months
from dual;
How to substract 6 months:
select add_months(to_date('31-01-2014', 'dd-mm-rrrr'),-6 ) add_months
from dual;
**** Yes it's tha same function just using a negative number.
And thats all for now.
Hope it helps some one.
lunes, 12 de mayo de 2014
How know to which responsibilities it's associated a function?
/*
get Responsibilities associated to Funtions
Only the funtions not Excluded
*/
WITH DAT
AS (SELECT 'FND_FORM_FUNCTIONS-' || fff.function_id ID,
FUNCTION_NAME,
USER_FUNCTION_NAME,
DESCRIPTION,
'FUNCTION' DATA_TYPE,
APPLICATION_ID,
CAST (NULL AS DATE) START_DATE,
CAST (NULL AS DATE) END_DATE,
CREATION_DATE,
CREATED_BY,
LAST_UPDATED_BY,
LAST_UPDATE_DATE,
CAST (NULL AS VARCHAR2 (480)) ASOCIATED_function_name,
CAST (NULL AS NUMBER) function_application_id,
'FND_FORM_FUNCTIONS-' || fff.function_id EXC
FROM FND_FORM_FUNCTIONS_VL fff
UNION ALL
SELECT 'FND_MENUS-' || MENU_ID,
MENU_NAME,
USER_MENU_NAME,
DESCRIPTION,
'MENU' DATA_TYPE,
NULL APPLICATION_ID,
CAST (NULL AS DATE) START_DATE,
CAST (NULL AS DATE) END_DATE,
CREATION_DATE,
CREATED_BY,
LAST_UPDATED_BY,
LAST_UPDATE_DATE,
CAST (NULL AS VARCHAR2 (480)) function_name,
CAST (NULL AS NUMBER) function_application_id,
'FND_MENUS-' || MENU_ID
FROM fnd_menus_VL fm
UNION ALL
SELECT 'FND_RESPONSIBILITY-' || RESPONSIBILITY_ID || '-' || APPLICATION_ID,
RESPONSIBILITY_KEY,
RESPONSIBILITY_NAME,
DESCRIPTION,
'RESPONSIBILITY',
APPLICATION_ID,
START_DATE,
END_DATE,
CREATION_DATE,
CREATED_BY,
LAST_UPDATED_BY,
LAST_UPDATE_DATE,
CAST (NULL AS VARCHAR2 (480)) function_name,
CAST (NULL AS NUMBER) function_application_id,
'FND_RESPONSIBILITY-' || RESPONSIBILITY_ID || '-' || APPLICATION_ID
FROM fnd_responsibility_vl
UNION ALL
SELECT 'FND_MENU_ENTRIES-' || MENU_ID || '-' || ENTRY_SEQUENCE,
CAST (ENTRY_SEQUENCE AS VARCHAR2 (4000)),
PROMPT,
ent.DESCRIPTION,
'MENU ITEM ' || NVL2 (fun.TYPE, '-' || fun.TYPE, '-SUBMENU'),
NULL APPLICATION_ID,
CAST (NULL AS DATE) START_DATE,
CAST (NULL AS DATE) END_DATE,
ent.CREATION_DATE,
ent.CREATED_BY,
ent.LAST_UPDATED_BY,
ent.LAST_UPDATE_DATE,
FUN.function_name,
FUN.APPLICATION_ID function_application_id,
'FND_FORM_FUNCTIONS-' || fun.function_id EXC
FROM FND_MENU_ENTRIES_VL ent, FND_FORM_FUNCTIONS_VL fun
WHERE 1 = 1
AND PROMPT IS NOT NULL
AND NVL (ent.GRANT_FLAG, 'Y') = 'Y'
AND (ent.function_id IS NOT NULL OR SUB_MENU_ID IS NOT NULL)
AND ent.function_id = fun.function_id(+)
),
REL
AS (SELECT 'FND_RESPONSIBILITY-' || RESPONSIBILITY_ID || '-' || APPLICATION_ID PAR, 'FND_MENUS-' || MENU_ID CH FROM FND_RESPONSIBILITY
UNION ALL
SELECT 'FND_RESPONSIBILITY-' || RESPONSIBILITY_ID || '-' || APPLICATION_ID PAR, 'FND_REQUEST_GROUPS-' || REQUEST_GROUP_ID CH
FROM FND_RESPONSIBILITY
UNION ALL
SELECT NULL PAR, 'FND_RESPONSIBILITY-' || RESPONSIBILITY_ID || '-' || APPLICATION_ID CH
FROM FND_RESPONSIBILITY
UNION ALL
SELECT 'FND_MENUS-' || MENU_ID PAR, 'FND_MENU_ENTRIES-' || MENU_ID || '-' || ENTRY_SEQUENCE CH FROM FND_MENU_ENTRIES
UNION ALL
SELECT 'FND_MENU_ENTRIES-' || MENU_ID || '-' || ENTRY_SEQUENCE par,
NVL2 (SUB_MENU_ID, 'FND_MENUS-' || SUB_MENU_ID, 'FND_FORM_FUNCTIONS-' || function_id)
FROM FND_MENU_ENTRIES
)
,
FN AS (
SELECT 'FND_RESPONSIBILITY-'||RESPONSIBILITY_ID|| '-' || APPLICATION_ID ID, DECODE (RULE_TYPE, 'F', 'FND_FORM_FUNCTIONS-' || ACTION_ID, 'M', 'FND_MENUS-' || ACTION_ID) RESP_ID
FROM FND_RESP_FUNCTIONS
)
SELECT tree.FUNCTION_NAME RESP_KEY,
tree.USER_FUNCTION_NAME RESP_DESCRIPTION,
tree.RESP_NAME function_name,
tree.RESP_DESCRIPTION USER_FUNCTION_NAME,
tree.NAVIGATION
FROM (SELECT CONNECT_BY_ROOT function_name RESP_NAME,
CONNECT_BY_ROOT USER_FUNCTION_NAME RESP_DESCRIPTION,
CONNECT_BY_ROOT DAT.APPLICATION_ID RESP_APPLICATION_ID,
CONNECT_BY_ROOT DAT.ID RESP_ID,
CONNECT_BY_ROOT dat.DATA_TYPE RESP_DATA_TYPE,
SYS_CONNECT_BY_PATH (function_name || ':' || USER_FUNCTION_NAME, '>') tree,
SYS_CONNECT_BY_PATH (DECODE (data_type,'RESPONSIBILITY',CAST (NULL AS VARCHAR2 (80)),function_name || ':' || USER_FUNCTION_NAME), '>') tree_NO_RESP,
SYS_CONNECT_BY_PATH (LPAD (FUNCTION_NAME, 20, '0'), '>') ORD_FUN,
SYS_CONNECT_BY_PATH (CAST (DECODE (data_type, 'MENU', CAST (NULL AS VARCHAR2 (80)), USER_FUNCTION_NAME || '-') AS VARCHAR2 (80)), '>')
NAVIGATION,
DAT.*,
cr.user_name CREATED_BY_NAME,
upd.user_name LAST_UPDATED_BY_NAME,
REL.par,
rel.ch
FROM DAT,
REL,
fnd_user cr,
fnd_user upd
WHERE dat.ID = rel.ch
AND dat.created_by = cr.user_id(+)
AND dat.last_updated_by = upd.user_id(+)
CONNECT BY NOCYCLE PRIOR par = ch
START WITH (
USER_FUNCTION_NAME = :P_NAME-->>NAME OF THE FUNCTION HERE
)
)
tree ,FN
WHERE DATA_TYPE='RESPONSIBILITY'
AND RESP_DATA_TYPE='FUNCTION'
AND tree.RESP_ID=fn.RESP_ID(+)
AND tree.ID=fn.id(+)
and fn.id is null;
lunes, 9 de mayo de 2011
Concurrents Hello World !!!!!
Así que primero un poco de teoría:
Concurrente: Es el medio que tienen los usuarios para ejecutar procesos en el servidor, sin tener acceso al usuario APPS ( Pon ningun motivo un usuario debe tener acceso a esta cuenta, incluso ni siquiera los desarrolladores deberiamos tener acceso a este usuario). La mayoría de las ejecuciones de concurrente se realizan por medio del menu:
ver->solicitudes->ejecutar nueva solicitud->solicitud unica
Si seleccionan en el recuadro amarillo, nos mostrara la lista de programas a los que tenemos acceso.
Ahora que ya se como ejecutarlo como rayos se crean estas cosas.
5 Pasos:
1.- Se genera un ejecutable, esto quiere decir cualquier cosa que se va a procesar en el servidor , la EBS soporta ejecutables pro C, java, perl, pl/sql,reports, etc. (el ejemplo que les daré esta en pl/sql).
ejemplo:
CREATE OR REPLACE PROCEDURE APPS.XXX_TST (errbuf OUT VARCHAR2
/*Mensaje que le regresa el procedimiento al adminstrador de concurrente, este mensaje se muestra en el administrador de concurrente*/ , retcode OUT NUMBER/*Codigo de error que el concurrente regresa al administrador de concurrente sobre el estatus de del concurrente: retcode :=0; El concurrente finaliza normal sin color retcode :=1; El concurrente finaliza en ADVERTENCIA color Amarillo retcode :=2; El concurrente finaliza en ERROR color rojo */,oper1 varchar2 ,oper2 NUMBER )
IS BEGIN
/* apps.fnd_file.output & apps.fnd_file.log constantes que represntan sobre que archivo se realizaran las operaciones del paquete fnd_file. apps.fnd_file.put(which,buff); este comando escribe en el archivo seleccionado los datos que se coloquen en el segundo parametro de entrada. apps.fnd_file.new_line(which,lines);este comando escribe en el archivo seleccionado tantos saltos de linea como se indique en el segundo parametro apps.fnd_file.put_line(which,buff);este comando escribe en el archivo seleccionado los datos que se coloquen en el segundo parametro de entrada concatenados con un salto de linea. */
apps.fnd_file.put(apps.fnd_file.output,'Linea 1 Hola Mundo');
apps.fnd_file.new_line(apps.fnd_file.output, 2);
apps.fnd_file.put(apps.fnd_file.output,'Linea 3 Hola Mundo');
apps.fnd_file.put(apps.fnd_file.output,'-Linea 3 Hola Mundo parte 2');
apps.fnd_file.new_line(apps.fnd_file.output, 1);
apps.fnd_file.put_line(apps.fnd_file.output, 'Linea 4 Hola Mundo');
apps.fnd_file.put(apps.fnd_file.output,'Linea 5 Hola Mundo');
apps.fnd_file.put(apps.fnd_file.log,'Linea LOG 1 Hola Mundo');
apps.fnd_file.new_line(apps.fnd_file.log, 2);
apps.fnd_file.put(apps.fnd_file.log,'Linea LOG 3 Hola Mundo');
apps.fnd_file.put(apps.fnd_file.log,'-Linea LOG 3 Hola Mundo parte 2');
apps.fnd_file.new_line(apps.fnd_file.log, 1);
apps.fnd_file.put_line(apps.fnd_file.log, 'Linea LOG 4 Hola Mundo');
apps.fnd_file.put(apps.fnd_file.log,'Linea LOG 5 Hola Mundo'); errbuf:='HAY ALERTAS';
retcode :=1;
errbuf:='HAY ERRORES';
retcode :=2;
errbuf:='NO HAY ERRORES';
retcode :=0;
END;
2.- Se define el ejecutable, desde la responsabilidad Desarrollador de aplicaciones(Application Developer)/Administrador de Sistema(System Administrator) en el menu:Concurrente->Programa->Ejecutable(Concurrent->Program->Executable) se capturan los datos de tu ejecutable. se podría decir que esta pantalla es solo una definición global del ejecutable.
3.- Se define el programa desde la responsabilidad Desarrollador de aplicaciones(Application Developer)/Administrador de Sistema(System Administrator) en el menu:Concurrente->Programa>Definir->(Concurrent->Program->Define) , aquí se capturan los datos que le servirán al usuario para ejecutar su programa, como son : cual es el ejecutable que utilizara?, con que parámetros?, que parámetro es obligatorio? este programa es incompatible con otro? que tipo de salida da este programa?, etc. aqui les dejo un ejemplo de la definición de programa.
4.- Se define quien va a ejecutar este programa, en la ebs el primer nivel donde se define que puede hacer un usuario es la responsabilidad que este tiene, a esa responsabilidad se le agregan todas las funcionalidades que el usuario debería ser capaz de realizar, ejemplo:
Listo !!!! una vez que ya lograron este paso, ya pueden ejecutar el programa que ustedes realizaron.
Ahora lo ejecutamos y que sucede, dependiendo de la forma en que hayan codificado los códigos de error, el proceso puede finalizar:
a) 2300206 retcode:=0; ejemplo de proceso normal.
b) 2300210 retcode:=1; ejemplo de proceso con advertencias.
c) 2300206 retcode:=2; ejemplo de proceso con error.
Queda del lado del programador el colocar el retcode que le ayude al usuario a identificar mejor la situación en la que se ejecuto el proceso.
Como detalle adicional si como programador no tocas esa variable, el proceso se marca como finalizado
correctamente cuando termina su ejecución sin lanzar excepciones.
Un proceso de pl/sql, hereda los datos de la sesión con la que se encuentra conectado, que quiere decir esto: Que no se requiere ejecutar ni APPS.FND_GLOBAL.APPS_INITIALIZE.
Con esto queda el ejemplo de como realizar la creación y ejecución de un proceso concurrente escrito en PL/SQL.
En el próximo articulo daré un ejemplo en reports.
martes, 5 de abril de 2011
Updating Twitter from the database, using PL/SQL and OAuth.
El objeto que se creo basándome en los ejemplos que trae consigo el api fue el siguiente:
public final class XXX_JTWEET{
public static String update_status(String argument)
/* update_status funciona tal cual el ejemplo es hard code, pero ayuda mucho a ver como funciona por lo que la dejo para su uso posterior*/public static String get_auth_url(String l_proxy ,String l_proxy_user ,String l_proxy_pass ,String l_proxy_port ,String l_AuthConsumerKey ,String l_ConsumerSecret ,String l_user ,String l_password )
/* get_auth_url esta función reducida nos regresa la url sobre la que se debe autorizar el acceso de la aplicación a nuestra cuenta de twitter*/
String set_status(String l_proxy
,String l_proxy_user
,String l_proxy_pass
,String l_proxy_port
,String l_AuthConsumerKey
,String l_ConsumerSecret
,String l_token
,String l_token_secret
,String l_access_token
,String l_access_token_secret
,String l_pin
,String l_status
)
}
/* set_status con la información obtenida de la página da autorización publica el estatus en el twitter*/
les regreso al programa, este paso se realiza una sola vez
/*enciendan dbms ouput para ver los resultados*/
/*esta parte del codigo unicamente es para cuando registran su programa ante twitter*/
declare
RetVal varchar2(4000);
begin
dbms_output.put_line(XXX_JTWEET_PKG.INITIALIZE (1));
dbms_output.put_line(xxx_jtweet_pkg.get_auth_url(false));
COMMIT;
END;
/
/*una vez que van a la pagina que les regreso el programa anterior deben ingresar el codigo que
*/Una vez mas los archivos del proyecto se encuentran disponibles en: http://sourceforge.net/projects/ora-tweet/
begin
xxx_jtweet_pkg.SET_PIN('2667137');
commit;
end;
/*Así es como deberían enviar los mensajes a twitter desde sus programas */
begin
/*al inicio del programa */
dbms_output.put_line(XXX_JTWEET_PKG.INITIALIZE (1));
/*Cada vez que desean mandar algo*/
dbms_output.put_line(xxx_jtweet_pkg.UPDATE_STATUS('hi from plsql v1.16'));
end;
Cualquier duda que tengan no duden en hacérmela llegar por medio del blog.
Repasemos rápidamente antes de terminar. lo que se nesecita para poder realizar el uso del api de twitter es:Consumer Secret/*Los obtienes al registrar el APP*/
AuthConsumerKey /*Los obtienes al registrar el APP*/
Request token /¨*Lo obtienes cuando se genera el auth url*/
Request token secret /¨*Lo obtienes cuando se genera el auth url*/
pin /*Se obtiene al ingresar n la tienda de musical pin a la oauth url*/
access_token /*Se obtiene al ingresar el pin a la oauth url*/
access_token_secret /*Se obtiene al ingresar el pin a la oauth url*/
Ahora si felices Tweets
viernes, 1 de abril de 2011
Oracle 11gR2 XE Beta is now available
Project Status Inquiry (PSI) Consulta de estado de 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. |
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
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
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 ?
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:
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 ¡¡¡
sábado, 10 de abril de 2010
El tiempo Vuela.
Bueno a continuación les coloco una muestra de cómo insertar a la tabla GL_INTERFACE y no morir en el intento.
/* Formatted on 16/06/2010 10:41:05 AM (QP5 v5.115.810.9015)
Autor:Javier Hernández Lemuz
E-MAIL:ciberbuster59@hotmail.com */
INSERT INTO gl_interface (status
,ledger_id
,accounting_date
,currency_code
,actual_flag
,user_je_category_name
,user_je_source_name
,currency_conversion_rate
,segment1
,segment2
,segment3
,segment4
,segment5
,segment6
,segment7
,segment8
,entered_dr
,entered_cr
,reference1
,reference2
,reference4
,reference5
,reference6
,reference10
,period_name
,GROUP_ID
,set_of_books_id
,date_created
,created_by)
VALUES ('NEW'
,-1
,TO_DATE ('01/23/201000:00:00'
,'MM/DD/YYYYHH24:MI:SS')
/*Fecha contable*/
,'MXN'
/*Moneda*/
,'A'
,'TRANSFERENCIAS'
/*Origen:asegurence de colocar el valor que corresponda al idioma con el que van a importar las pólizas ya que si no la interfaz puede no reconocer el valor*/
,'CATEGORÍA'
/*Categoria:asegurence de colocar el valor que corresponda al idioma con el que van a importar las polizas ya que si no la interfaz puede no reconocer el valor*/
,1
,'063'
/*segmentos de la estructura contable*/
,'01'
,'367'
,'000'
,'11411'
,'001'
,'000'
,'000'
,0
/*crédito->abono recordemos siempre que si las sumaroria de los cargos ya abonos no cuadran, la interfaz no va a realizar la importación */
,1079.58
/*debito->cargo */
,'NOMBRELOTE'
,'DESCRIPCIÓNLOTE'
,'NOMBREPÓLIZA'
,'DESCRIPCIÓNPÓLIZA'
,'REFERENCIADELAPÓLIZA'
,'DESCRIPCIÓNDELALINEO'
,'MAY-2010'
,127097
,-1
,SYSDATE
,-1);
Espero les sea útil.
Encontraran toda esta y más información dentro del documento:
Reference:
Oracle® General Ledger User's Guide
Release 12
Part No. B31218-01
lunes, 5 de octubre de 2009
Basicos - Ya la instale ahora que sigue.
La estructura basica de un query en SQL:
Select [que quieres saber o que columnas deseas que te devuelva ]
from [de donde se sacaran los datos ]
where [cuales son las condiciones para seleccional los datos].
Entonces vamos a ver ejemplos de querys para dejar claro que podemos realizar:
Lo primero es conectarnos a nuestra recien instalada base de datos.
La manera mas sencilla es
inicio->programas->Oracle Database 10g Express Edition->Go To Database Home Page
Una vez ahi lo primero que te va a pedir es ingrsar tu usuario y password
El usuario es SYSTEM y el PASSWORD es el que indicaste durante la instalación.
Ahora una vez conectado ingresas al menu Administracion->Usuarios Base Datos-> Ahi seleccionas el usuario HR, en la opcion "estado de la cuenta" seleccionas desbloqueado y le pones una contraseña. Una ves hecho esto seleccionas la opcion Modificar Usuario para guardar los cambios. Y listo ahora puedes conectarte a el usuario HR que es el usuario de ejemplo de esta base de datos que cuenta con un conjunto de tablas que sirven para comenzar con los ejemplos.
















