Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 27-05-2005
JoanKa JoanKa is offline
Miembro
 
Registrado: ene 2005
Posts: 92
Poder: 20
JoanKa Va por buen camino
Trigger, generador y SP relacionarlo con Delphi

Ante todo gracias por la atencion prestada.

Bueno les cuento que recien estoy empezando con esto de Firebird, es decir los triggers, SP y generadores y soy novato en esto y tengo algunos problemas


Tengo la siguiente tabla:
CREATE TABLE CLIENTE (
CODI_CLI VARCHAR(10) NOT NULL,
NOMB_CLI VARCHAR(30),
ALTA_CLI DATE,
OBSE_CLI BLOB SUB_TYPE 2 SEGMENT SIZE 8192,
PAGO_CLI FLOAT
);


asi como este Procedimiento almacenado

CREATE PROCEDURE INSERTAR_CLIENTE (
COD VARCHAR(10),
NOM VARCHAR(30),
ALT DATE,
OBS BLOB SUB_TYPE 1 SEGMENT SIZE 80,
PAG FLOAT)
AS
begin
INSERT INTO Cliente (CODI_CLI, NOMB_CLI, ALTA_CLI,PAGO_CLI, OBSE_CLI)
values (:COD, :NOM, :ALT, :PAG, :OBS);
end


y en Delphi hago lo siguiente:

with IBStoredProc1 do
begin
Params[0].AsString := txt_codigo.Text;
Params[1].AsString := txt_nombre.Text;
Params[2].AsDate := StrToDate(txt_fecha.Text);
Params[3].AsMemo := txt_observaciones.Text;
Params[4].AsFloat :=StrToFloat(txt_pago.Text);
ExecProc;
end;


Lo que hago con esto es registrar a un cliente y me lo hace correctamente hasta aca no tengo problemas todo OK.

Pero ahora quiero que el CODI_CLI SE EJECUTE AUTOMATICAMENTE, para eso
en firebird e creado un generador y un trigger.
Es decir.

CREATE GENERATOR CODI_GENER;
SET GENERATOR CODI_GENER TO 0;




CREATE TRIGGER INSERTAR_CODI FOR CLIENTE
ACTIVE BEFORE INSERT POSITION 0
AS
begin
if (new.codi_cli is null) then
new.codi_cli=gen_id(codi_gener,1);
end

Ahora mis preguntas son las siguientes:

1.- Quiero que objeto txt_codigo se edite el CODI_CLI de la siguiente manera :
CLI0010001,
CLI0010002,
CLI0010003,
CLI0010004.......

Para esto me parece que tengo que tener 2 partes CLI + NUMERO, es decir la la palabra CLI fija y NUMERO autoincremental (quiero que sea apartir de 1000). Como lo podria hacer esto.

2. Como se haria para relacionar el procedimiento almacenado y el trigger con delphi para que pueda registrar al cliente.
Viendo por alli informacion tengo que eliminar la linea siguiente

Params[0].AsString := txt_codigo.Text;

ya que el trigger me lo haria automaticamente.

3. Como puedo poner el codigo en delphi para llamar al trigger.


Gracias y Saludos a todos
Responder Con Cita
  #2  
Antiguo 27-05-2005
Avatar de defcon1_es
defcon1_es defcon1_es is offline
Miembro
 
Registrado: mar 2004
Ubicación: Cuenca - España
Posts: 533
Poder: 21
defcon1_es Va por buen camino
Cita:
Empezado por JoanKa
Pero ahora quiero que el CODI_CLI SE EJECUTE AUTOMATICAMENTE
Lo que quieres es que se le asigne un valor automáticamente, ¿no?

Cita:
Empezado por JoanKa
1.- Quiero que objeto txt_codigo se edite el CODI_CLI de la siguiente manera :
CLI0010001,
CLI0010002,
CLI0010003,
CLI0010004.......

Para esto me parece que tengo que tener 2 partes CLI + NUMERO, es decir la la palabra CLI fija y NUMERO autoincremental (quiero que sea apartir de 1000). Como lo podria hacer esto.
Prueba esto:
Código SQL [-]
CREATE TRIGGER INSERTAR_CODI FOR CLIENTE
ACTIVE BEFORE INSERT POSITION 0
AS
begin
/* if (new.codi_cli is null) then 
No hace falta que preguntes si tiene valor o no, 
porque quieres asignarle el valor automaticamente SIEMPRE.
*/ 
new.codi_cli = "CLI" || CAST(gen_id(codi_gener,1) AS VARCHAR(7));
end
Pruebalo, yo no he podido comprobar si funciona, te lo escribo "de cabeza".
Ten cuidado por si el resultado es mayor de 10 caracteres, que es la long. máxima que le has dado a ese campo.
Puede producirse el error "Aritmetic exception or numeric overflow"


Cita:
Empezado por JoanKa
2. Como se haria para relacionar el procedimiento almacenado y el trigger con delphi para que pueda registrar al cliente.
El trigger es automático, y como se activa antes de insertar el registro,
con hacer "DataSet.Insert" (y luego el Post) sería suficiente.

Cita:
Empezado por JoanKa
3. Como puedo poner el codigo en delphi para llamar al trigger.
DataSet.Insert o DataSet.Append
__________________
Progress Openedge
https://abevoelker.com/progress_open...dered_harmful/


Delphi forever...
Responder Con Cita
  #3  
Antiguo 27-05-2005
JoanKa JoanKa is offline
Miembro
 
Registrado: ene 2005
Posts: 92
Poder: 20
JoanKa Va por buen camino
Hola defcon1_es .

Sabes me fue de maravilla todo ok.

Creo que no me di a entender en el Tercer Punto a ver si me explico:

Supongamos que el ultimo cliente tiene el codigo
...
...
CLI15201 | Pedro Pablo | 11/05/2005 | Probando Observaciones.... | 100,50

Ahora ejecuto mi programa en delphi y tengo un textbox en el cual quiero que me muestre el codigo siguiente al ultimo ingresado (CLI15201) es decir me debe mostrar el codigo actual, es decir, CLI15202 y luego lo grabare en la base de datos.

Como se podria hacer esto en delphi.
Responder Con Cita
  #4  
Antiguo 27-05-2005
Avatar de Héctor Randolph
[Héctor Randolph] Héctor Randolph is offline
Miembro Premium
 
Registrado: dic 2004
Posts: 882
Poder: 20
Héctor Randolph Va por buen camino
Hola Joanka!

Como bien lo dice Daniel en su respuesta anterior el Trigger no lo puedes llamar desde Delphi porque ese trabajo la corresponde sólo al servidor en Firebird, pero en su lugar puedes llamar un procedimiento almacenado para obtener el valor del generador.

Por ejemplo:

Código SQL [-]
CREATE PROCEDURE GET_NEXT_CODI_CLIE 
RETURNS (NUEVO_CODI_CLIE VARCHAR(10))
AS
BEGIN
   /*Obtienes el valor actual del generador sin incrementarlo*/
  /*Observa el incremento en cero en la función gen_id*/
  NUEVO_CODI_CLIE="CLI" || CAST(gen_id(codi_gener,0)+1 AS VARCHAR(7));
  SUSPEND;
END

Bueno por lo pronto te doy la idea, no tengo el Delphi a la mano y no he podido probarlo.

Un Saludo!
Responder Con Cita
  #5  
Antiguo 29-05-2005
JoanKa JoanKa is offline
Miembro
 
Registrado: ene 2005
Posts: 92
Poder: 20
JoanKa Va por buen camino
Hola Amigos Gracias por la respuesta pero tengo un problemilla al momento de mostrar o recibir el codigo siguiente (es decir si en la Tabla tengo como ultimo cliente el CLI10052 en el textbox me debe mostrar el siguiente: CLI10053) en el TextBox (txt_codigo) pero no me lo muestra,

txt_codigo.Text := IBStoredProc2.Params[0].AsString;

El procedimiento es el que me dijo HECTOR

CREATE PROCEDURE CODIGO_SIGUIENTE
RETURNS ( NUEVO_CODI_CLIE VARCHAR(10))
AS
begin
NUEVO_CODI_CLIE='CLI' || CAST(gen_id(codi_gener,0)+1 AS VARCHAR(7));
suspend;
end
No se que estara pasando o estoy recibiendo mal el parametro que se envia del SP..

Gracias
Responder Con Cita
  #6  
Antiguo 29-05-2005
Avatar de kinobi
kinobi kinobi is offline
Miembro
 
Registrado: may 2003
Posts: 2.621
Poder: 24
kinobi Va por buen camino
Hola,

si el valor del código se va "armar" en el cliente, yo recastaría el valor del generador con una consulta:

Código SQL [-]
select gen_id(MiGenerador, 0) from rdb$database

o

select gen_id(MiGenerador, 0)+1 from rdb$database

así evito tener que crear un procedimiento en el servidor. Si no se quiere hacer la conversión de tipos en el cliente, aplicar los CAST correspondientes en la consulta.

Saludos.

Última edición por kinobi fecha: 29-05-2005 a las 12:47:41.
Responder Con Cita
  #7  
Antiguo 30-05-2005
JoanKa JoanKa is offline
Miembro
 
Registrado: ene 2005
Posts: 92
Poder: 20
JoanKa Va por buen camino
Hola nuevamente.

Lo que pasa es q como deberia hacerlo.

Que Componente IBX debo colocar en mi formulario para poder hacer esta consulta, me lo podrias indicar y como hacerlo.

Soy Nuevo en esto y todavia no pillo el truco de los Trigger y SP.

Gracias
Responder Con Cita
  #8  
Antiguo 30-05-2005
Avatar de kinobi
kinobi kinobi is offline
Miembro
 
Registrado: may 2003
Posts: 2.621
Poder: 24
kinobi Va por buen camino
Hola,

Cita:
Empezado por JoanKa
Que Componente IBX debo colocar en mi formulario para poder hacer esta consulta,
Un TIBQuery

Cita:
Empezado por JoanKa
me lo podrias indicar y como hacerlo.
Supongo que la ayuda del componente tendrá algún ejemplo de uso. No es que no quiera ponerte un ejemplo, pero hace siglos que no uso Delphi y no me gustaría ponerte un código que no funcionase. Pero, vamos, el uso de TIBQuery es muy similar al TQuery de la VCL.

Cita:
Empezado por JoanKa
Soy Nuevo en esto y todavia no pillo el truco de los Trigger y SP.
La consulta en cuestión no tiene niguna relación ni con los triggers ni con los procedimientos, es, simplemente, una consulta al servidor que te devuelve el valor de un Generador.

Saludos.
Responder Con Cita
  #9  
Antiguo 30-05-2005
inferno inferno is offline
Miembro
 
Registrado: may 2005
Posts: 10
Poder: 0
inferno Va por buen camino
hola Hector ,es Julio ramos mi problema es el siguiente muy paresido al de JoanKa:Tengo las siguiente tablas:
CREATE TABLE tblfacturas (
COD_factura long NOT NULL,
NOMB_CLI VARCHAR(30),
);
CREATE TABLE tbltiene
(
COD_factura long NOT NULL, /* este campo esta referenciado al campo clave de tblfacturas*/

cod_articulo VARCHAR(10) NOT NULL/* este campo esta referenciado al campo clave de tblarticulo*/
);


CREATE TABLE tblarticulo
(

cod_articulo VARCHAR(10) NOT NULL,
nomb_articulo VARCHAR(50) NOT NULL
);


asi como este Procedimiento almacenado

CREATE PROCEDURE INSERTAR_factura (
COD_factura VARCHAR(10),
NOM_cli VARCHAR(30),
AS
begin
INSERT INTO tblfacturas (CODI_factura, NOMB_CLI, )
values (:COD_factura, :NOM_cli);
end


tengo este trigger
CREATE GENERATOR CODI_GENER;
SET GENERATOR CODI_GENER TO 0;


CREATE TRIGGER INSERTAR_CODI FOR CLIENTE
ACTIVE BEFORE INSERT POSITION 0
AS
begin
if (new.cod_factura is null) then
new.cod_factura=gen_id(codi_gener,1);/*este numero hay manera de sacarlo al momento de ser generado por alguna consulta,porcedimeinto desde delphi,el manejador*/
end
como puedes ver necesito el numero que genera el trigger al momento de insertar el tabla factura para colocarlo en tabla tbltiene en el campo cod_factura
este procedure lo puede hacer la cosa es que si el sistema esta en red me entiendes varias aplicaciones conectadas a la misma base de datos (cliente servidor).Porque un cliente "a" ejecuta el procedimiento insertar_factura y otro cliente "b" tambien ejecuta el procedimiento insertar_factura entoces caimos en esto que el cliente "b" ejecuta primero el procedimiento que retorna el numero generado por ejemplo el procedimeinto tu yo (CREATE PROCEDURE GET_NEXT_CODI_CLIE), al momento de seleccionar el valor selecciona la correcta o selecciona el ultimo numero generado y no es la correcta por primero el cliente "a" solicito el procedimiento insertar_factura.
CREATE PROCEDURE GET_NEXT_CODI_CLIE
RETURNS (NUEVO_CODI_CLIE long)
AS
BEGIN
/*Obtienes el valor actual del generador sin incrementarlo*/
/*Observa el incremento en cero en la función gen_id*/
NUEVO_CODI_CLIE=CAST(gen_id(codi_gener,0)+1 AS VARCHAR(7));
SUSPEND;
END

espero que me puedas ayudar....
Responder Con Cita
  #10  
Antiguo 30-05-2005
Avatar de Héctor Randolph
[Héctor Randolph] Héctor Randolph is offline
Miembro Premium
 
Registrado: dic 2004
Posts: 882
Poder: 20
Héctor Randolph Va por buen camino
Hola nuevamente!

Cita:
Empezado por inferno
como puedes ver necesito el numero que genera el trigger al momento de insertar el tabla factura para colocarlo en tabla tbltiene en el campo cod_factura
Bueno, voy a suponer que estás utilizando Delphi, tengo una respuesta que tal vez se ajuste a tus necesidades, las siguientes líneas las saqué de este hilo:

Conectar Trigger con Delphi:

http://www.clubdelphi.com/foros/show...2152#post82152

Cita:
Empezado por HECTOR RANDOLPH
Si utilizas los componentes IBX que vienen con el Delphi, me refiero a IBDataSet o IBQuery puedes encontrar una propiedad que se llama GeneratorField

Las opciones que tienes que configurar son :

Primero indicas cual es el generador y campo que afecta

Generator: CODI_GEN
Field: COD_FACTURA
Increment By: 1

Después indicas en que momento se actualiza el generador

Apply Event
- On New Record
- On Post
- On Server

La selección de Apply Event es al gusto del cliente, por jemplo si seleccionas On New Record el generador se dispara al momento de insertar un registro (IBQuery1.Insert) y el campo COD_FACTURA se actualiza inmediatamente con el valor correspondiente en la secuencia, el inconveniente en este caso es que si cancelas la inserción (IBQuery1.Cancel) el generador ya se actualizó y se salta ese número de la secuencia.

Para evitar esto puedes elegir On Post de esta forma el generador se actualiza cuando guardas el registro (IBQuery1.Post).

La última opción On Server como su nombre lo indica es dejar que el servidor se encarge de actualizar el generador.
En teoría, si aplicas este método, el campo COD_FACTURA de la tabla tblfacturas tendrá siempre el valor correcto del generador después de una inserción.

Espero que sea útil y seguimos en contacto.
Responder Con Cita
  #11  
Antiguo 31-05-2005
JoanKa JoanKa is offline
Miembro
 
Registrado: ene 2005
Posts: 92
Poder: 20
JoanKa Va por buen camino
Vamos a ver.

Yo lo resolvi este problema de la Siguiente Manera

1° Tenia que crear un SP donde obtendria el codigo siguiente a grabar, es decir,

CREATE PROCEDURE CODIGO_SIGUIENTE
RETURNS (
NUEVO_CODI_CLIE VARCHAR(10))
AS
begin
NUEVO_CODI_CLIE='CLI' || CAST(gen_id(codi_gener,0)+1 AS VARCHAR(7));
suspend;
end

2. En delphi agrege Un IBQuery y Un DataSource
3. En la propiedad SQL del IBQUERY escribi : Select * from CODIGO_SIGUIENTE
4. En la Propiedad DATASET del DATASOURCE coloque IBQuery1
5. Ahora en el Objeto TBEDIT en su propiedad DATASOURCE escribi DATASOURCE1
6. y por ultimo en el Objeto TBEDIT en su propiedad DATAFIELD coloque: NUEVO_CODI_CLIE (que es el valor que retorna el SP).

Espero que te sirva.

Es obvio que para esto tienes que tener : IBDATABASE, IBTRANSACTION, y ver que haya conexion con Firebir

SALudos a TOdos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 13:10:00.


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
Copyright 1996-2007 Club Delphi