Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Ejecutar Procedimiento Almacenado en Trigger (https://www.clubdelphi.com/foros/showthread.php?t=14376)

AGAG4 18-09-2004 02:00:56

Ejecutar Procedimiento Almacenado en Trigger
 
Uso FireBird 1.50
Como se ejecuta un Procedimiento Almacenado en un Trigger, lo que pasa es que le quiero pasar un valor a un campo Antes de Insertar y Guardar un Registro, mediante un Procedimiento Almacenado que tengo, le paso como parámetros de Entrada la Sucursal y el Cliente y tengo como parámetro de Salida el Indice por ejemplo:
Código SQL [-]
 new.indice=execute procedure dame_indice_dpromociones(New.sucursal,new.cliente);
me marca en error en execute y si se lo quito no me reconoce la palabra reservada "Procedure".. Agradezco cuanlquier comentario.

jachguate 18-09-2004 02:22:25

Si el procedure devuelve un valor, recuperalo en un select.

Código SQL [-]
select indice
  from dame_indice(:valor1, :valor2)
 into :indice;

Hasta luego.

;)

AGAG4 18-09-2004 03:04:01

oki
 
Gracias Sr. Juan Antonio Castillo Hernández, así me funcionó, pero me sucede algo raro, lo que me pasa es que este Trigger se Dispará antes de que el dbGrid Graba en el Detalle, pero No me devuelve ningun valor, y si lo ejecuto a traves del Componente ibStoreProcedure, mandandole los parámetros del Pro. Alamcenado si me devuelve el Parámetro. De antemano Muchas Gracias.

jachguate 18-09-2004 04:59:10

No entendí bien tu planteamiento... lo que se decirte es que el trigger es totalmente independiente de cualquier dbgrid y cosas similares. Se disparará justo antes (before) o depues (after) de la insercion (insert), actualizacion (update) o borrado (delete) de un registro en el servidor de la base de datos.

Hasta luego.

;)

guillotmarc 18-09-2004 12:52:08

Hola.

Pruebalo de esta forma :

execute procedure dame_indice_dpromociones(new.sucursal, new.cliente) returning_values new.indice;

NOTA: Lo he escrito de memória, si no funciona, consulta la sintaxis de execute procedure, en la documentación de Firebird (aunque creo que es correcta).

Saludos.

AGAG4 18-09-2004 16:50:04

oki
 
Gracias Sr. Juan Antonio Castillo Hernández, ya se que un trigger se ejecuta antes de después de Insertar, Actualizar y Borrar, pero no se porque no se ejecuta cuando en el dbGrid "AUTOMATICAMENTE" ejecuta el POST de la Tabla(IbDataset) en donde en el ModifiSQL tengo un "UPDATE ......", ya le cambie a todos los estados al Trigger pero no me devuelve ningun valor, pero si mando a llamar el ibStoreProccedure en el "BeforePost" del IbDataset mandandole los parámetros de Entrada, si me devuelve el parámetro de Salida.

En el BeforePost del IbDataset tengo esto:
Código:

  tDPromocionSUCURSAL.value:=SucursalProm;
  tDPromocionCLIENTE.value:=ClienteProm;

Antes de que el dbGrid Guarde el Registro Ejecuta esto para añadirlo a la Llave Primaria, pero el Trigger no me devuelve nada, me marca que el Campo INDICE no tiene ningun valor para Guardar, este campo forma parte de la llave Primaria del Detalle, pero si pongo en este mismo evento un ibStoreProccedure si me devuelve el INDICE.

Ya lo probe como también me dice Sr. Marc Guillot, no me marca error en el Trigger pero también no me devuelve el ningún valor. No se que estaré haciendo mal, ó bien supuestamente en el dbGrid porque si al agregar un Nuevo registro "ACTUALIZA AUTOMATICAMENTE" el registro anterior y no se Dispará el Trigger. De antemano Gracias por sus Respuestas.

guillotmarc 18-09-2004 20:13:14

Hola.

Una posiblidad es que tu trigger asigne un valor en el campo, pero la sentencia de modificación que lanza el IBDataset le asigne un valor nulo, sobreescribiendo el valor asignado por el trigger.

Para evitarlo, el campo no debe estar en los campos persistentes del IDBataSet, o bien debe ser ReadOnly, o tener desactivado el flat pfInUpdate. NOTA: Como no utilizo IBX solo te lo puedo indicar de forma aproximada. (Si el IBDataSet tiene una sentencia SQL para el Update, quita ese campo de la sentencia).

Saludos.

AGAG4 20-09-2004 16:24:52

oki
 
Lo voy a probar..... Gracias por sus Respuestas.

AGAG4 20-09-2004 16:53:11

oki
 
Sinceramente ya revise todo, ya hice lo que me dijo pero no me devuelve ningun valor para el campo INDICE que tengop dentro del Trigger antes de Insertar un Registro en el Detalle, que raro, pero en código si me devuelve el valor, de todas formas Muchas Gracias por su respuesta.

jachguate 20-09-2004 18:13:57

Que ocurre si lanzas la sentencia update en isql o en ibexpert?

hasta luego.

;)

AGAG4 20-09-2004 20:10:12

oki
 
Si lanzo esta sentencia me llama el Trigger en donde llamará al Proc. Almacenado que me regresará el último INDICE del Detalle y me actualizará este mismo. Esto es si la llave Primaria SUCURSAL y CLIENTE tienen valores, pero si juego a que el "dbGrid" intente a disparar el Trigger no lo logra hacer. Espero me haya explicado .. Gracias.

jachguate 20-09-2004 20:29:40

:confused: la verdad no.

Un trigger se dispara independientemente de donde venga la sentencia update. Precisamente esa es una de sus razones de ser, y de sus principales ventajas.

Hasta luego.

;)

AGAG4 20-09-2004 22:12:09

oki
 
Estoy de acuerdo con usted, pero, corrigeme si estoy mal, si en un dbGrid lo enlazo a un ibDataset por medio de un DataSource, al abrir un Nuevo Registro en el dbGRid, manda a llamar la Instrucción Post+Insert, obviamente porque Graba el Registro Anterior e Inserta el Siguiente, entonces si manda la Instrucción "Post", porque no llama el Trigger si en la propiedad ModifiSQL del IbDataset tengo la sentencia SQL:
Código SQL [-]
size="1">update TFAC_DPROMOCIONES
size="1">set 
size="1">ARTICULO = :ARTICULO,
size="1">CLIENTE = :CLIENTE,
size="1">DESCTO = :DESCTO,
size="1">INDICE = :INDICE,
size="1">PRECIO = :PRECIO,
size="1">SUCURSAL = :SUCURSAL
size="1">where
size="1">CLIENTE = :OLD_CLIENTE and
size="1">INDICE = :OLD_INDICE and
size="1">SUCURSAL = :OLD_SUCURSAL
y en la Propiedad InsertSQL tengo
Código SQL [-]
size="1">insert into TFAC_DPROMOCIONES
size="1">(ARTICULO, CLIENTE, DESCTO, INDICE, PRECIO, SUCURSAL)
size="1">values
size="1">(:ARTICULO, :CLIENTE, :DESCTO, :INDICE, :PRECIO, :SUCURSAL)
Y el Trigger lo tengo Antes ó después de "Insertar" y "Modificar" y no me regresa nada.

En el Trigger tengo esto:
Código SQL [-]
execute procedure dame_indice_dpromociones(new.sucursal, new.cliente) returning_values new.indice;
if (new.indice=0) then
  new.indice=1;
Y en el Procedimiento Almacenado tengo esto:
Código SQL [-]
Select Max(indice)+1 from tfac_dpromociones
         where Sucursal=:Sucursal and
                Cliente=:Cliente
         into:xindice;
/*Donde :Sucursal y :Cliente Son Parámetros de Entrada y
   :XIndice es el Parámetro de Salida*/
Gracias por sus comentarios. Espero haberme explicado.

jachguate 21-09-2004 01:17:23

Hola Agag.

Creo que debes comenzar por separar las ideas. El dataset ejecutará la sentencia SQL apropiada (insert, update o delete) cuando se llame al método post.

Cuando se llama al método Insert, Delete, Append o Edit, el dataset normalmente llamará primero a su método post si es necesario, antes de intentar realizar la acción propia del método.

Todo esto ocurre en tu propia aplicación.

Los triggers residen en la base de datos, de manera que cuando el motor recibe una sentencia insert/update/delete ejecuta los triggers especificados para la tabla, de acuerdo a su sentencia de creación (before/after) y la sentencia específica.

Podes comprobar que el trigger se dispare y funcione correctamente conectandote via isql o ibExpert. Si el trigger funciona, entonces revisá la lógica de tu programa en delphi. Si no funciona, entonces revisá la lógica del trigger.

Hasta luego.

;)

AGAG4 21-09-2004 02:23:56

oki
 
Entonces en el dbGrid, cuando se inserta un registro el ibDataset manda a llamar su método Insert, pero no manda al motor de la base de datos la sentencia "INSERT INTO..", estoy mal????
Muchas Gracias por sus Respuestas.

jachguate 21-09-2004 02:41:24

ahora ya no. :D:D

AGAG4 21-09-2004 03:27:47

oki
 
oki
Gracias.


La franja horaria es GMT +2. Ahora son las 19:03:02.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi