martes, 27 de noviembre de 2012

Sentencia Merge - Oracle SQL y Plsql

La sentencia Merge nos sirve para combinar dos operaciones: Insertar y Actualizar. La función Merge nos permite hacer un update en caso de que la condición dada se cumpla o insertar en caso de que no se cumpla, es realmente muy útil.

Se puede usar a partir de Oracle 9i.

La sintaxis:



MERGE INTO <table_name>
USING <table_view_or_query>
ON (<condition>)
WHEN MATCHED THEN <update_clause>
WHEN NOT MATCHED THEN <insert_clause>
[LOG ERRORS <log_errors_clause> <reject limit <integer | unlimited>];



TABLE_NAME
Aqui debe especificar el nombre de la tabla o vista en la que va a insertar o actualizar. Si va a hacer un merge sobre una vista, ésta debe ser actualizable.

TABLE_VIEW_OR_SUBQUERY
En está se indica el origen de los datos que va a actualizar, puede ser una tabla, una vista o un subquery.

CONDITION
Especificas la condición para que el merge decida si debe actualizar o insertar. Esta condición es evaluada fila por fila, si la condición es verdadera, se ejecutará la clausula Update; si la condición es falsa, la base de datos insertará el registro desde el origen.

UPDATE_CLASE
Especifica los nuevos valores de la tabla a actualizar, en caso de que la condición sea verdadera. No puedes actualizar una columna que éste incluida en la Condición.

INSERT_CLAUSE
Especifíca los valores a insertar en caso de que la condición no sea verdadera. 

EJEMPLO

En el ejemplo tenemos una tabla de descuentos a clientes (desc_client), está llena con los clientes de la empresa con derecho a descuento hasta el momento. La tabla está asi

Id     Porc_desc
111      10
112      10
115      15
212      20

Vamos a hacer una sentencia para que a los clientes que han comprado más de 200 pesos en el año se les incluya en la tabla de descuentos con un 10% y a los que ya están se les suba le 1% (Es solo un ejemplo)

La sentencia sería:


MERGE INTO desc_client d
USING (select id, sum(valor) from facturas where anio=2012
       group by id having sum(valor)>200) f
ON (d.id=f.id)

WHEN MATCHED THEN update set d.porc_desc = d.porc_desc + 1
WHEN NOT MATCHED THEN insert (d.id, d.porc_desc)

values (f.id, 10);

El resultado, suponiendo que los clientes 111,115,205,206 superaron los 200 pesos en compras, sería:

Id     Porc_desc
111      11
112      10
115      16
212      20
205      10
206      10


viernes, 19 de octubre de 2012

Llamar reporte desde Forms sin mostrar ventana de Parámetros

Llamar reporte desde Forms sin mostrar ventana de Parámetros

Estoy llamando un reporte desde una forma, a pesar de que mando todos los parámetros al reporte, éste insiste en mostrarme la ventana de parámetros, no quiero eso, quiero que inmediatamente le ordene imprimir a mi forma se muestre el reporte con los parámetros que le he indicado.

Qué debo hacer?

Primero indicar los parámetros como siempre, algo así:

PROCEDURE IMPRIMIR IS
   list_id   ParamList;
BEGIN
    list_id := Create_Parameter_List('param');
  Add_Parameter(list_id,'PAR1',TEXT_PARAMETER,Valor_Par1);
  Add_Parameter(list_id,'
PAR2',TEXT_PARAMETER,Valor_Par2);
 Run_Product(REPORTS,'Name_Report',SYNCHRONOUS,RUNTIME,FILESYSTEM,list_id);
  Destroy_Parameter_List(list_id);

END;

Tienen que incluirse todos los parámetros que pide el reporte, para que éste no tenga la necesidad de mostrar la pantalla y pedir el faltante.
Así como está me va a mostrar la pantalla de parámetros, para que no lo haga agregamos 4 parametros más a la lista:

 Add_Parameter(list_id,'PARAMETERS',TEXT_PARAMETER,'NO');
 Add_Parameter(list_id,'PARAMFORM',TEXT_PARAMETER,'NO');   Add_Parameter(list_id,'COPIES',TEXT_PARAMETER,1);
 Add_Parameter(list_id,'DESTYPE',TEXT_PARAMETER,'PREVIEW');


El más importante PARAMFORM es el que realmente hace que no se muestre la pantalla de parámetros, los demás son para asegurarme que van a tener los valores necesarios.