PDA

Ver la Versión Completa : Creacion de un Stored Procedure


jafera
02-12-2011, 17:23:27
Buenas tardes.

Esta es mi primera incursion en los stored procedures.

Tengo una tabla maestra CU0001E de la que quiero sacar los valores de los campos C11, C10, C5, C6, C7 y C13.
Despues en la tabla destino CU0001 quiero hacer un update para que me actualize los campos LLICENCIA, NOM, COGNOM1, COGNOM2 y CODIUCI, siempre que se cumpla la condicion DNI=:DNI.

Este es el codigo del SP


COMMIT WORK;
SET AUTODDL OFF;
SET TERM ^ ;
/* Stored procedures */
CREATE PROCEDURE "ACTUALITZA_RFEC"
(
"LLICENCIA" VARCHAR(14) CHARACTER SET ISO8859_1,
"NOM" VARCHAR(20) CHARACTER SET ISO8859_1,
"COGNOM1" VARCHAR(25) CHARACTER SET ISO8859_1,
"COGNOM2" VARCHAR(25) CHARACTER SET ISO8859_1,
"CODIUCI" VARCHAR(12) CHARACTER SET ISO8859_1
)
AS
BEGIN EXIT; END ^

ALTER PROCEDURE "ACTUALITZA_RFEC"
(
"LLICENCIA" VARCHAR(14) CHARACTER SET ISO8859_1,
"NOM" VARCHAR(20) CHARACTER SET ISO8859_1,
"COGNOM1" VARCHAR(25) CHARACTER SET ISO8859_1,
"COGNOM2" VARCHAR(25) CHARACTER SET ISO8859_1,
"CODIUCI" VARCHAR(12) CHARACTER SET ISO8859_1
)
AS
declare variable dni_1 varchar(12) character set iso8859_1;
declare variable llicencia_1 varchar(14) character set iso8859_1;
declare variable nom_1 varchar(20) character set iso8859_1;
declare variable cognom1_1 varchar(25) character set iso8859_1;
declare variable cognom2_1 varchar(25) character set iso8859_1;
declare variable codiuci_1 varchar(12) character set iso8859_1;
begin
SELECT C11, C10, C5, C6, C7, C13
FROM CU0001E
INTO :DNI_1, :LLICENCIA_1, :NOM_1, :COGNOM1_1, :COGNOM2_1, :CODIUCI_1;
BEGIN
UPDATE CU0001
SET LLICENCIA=:LLICENCIA_1, NOM=:NOM_1, COGNOM1=:COGNOM1_1, COGNOM2=:COGNOM2_1, CODIUCI=:CODIUCI_1
WHERE DNI=:DNI_1;
END
SUSPEND;
end
^
SET TERM ; ^
COMMIT WORK;
SET AUTODDL ON;


Total que cuando lo llamo desde Delphi

F_ModulDades.Actualitza_RFEC.ExecProc;

me da un error "Required Param Value Not Set"
No se si me he olvidado algo, si he colocado las sentencias correctamente, etc...
Delphi 6 Firebird 1.5 componentes IBX

Casimiro Notevi
02-12-2011, 18:30:21
Así a simple vista creo que te sobran los begin, end y suspend;

begin
SELECT C11, C10, C5, C6, C7, C13
FROM CU0001E
INTO : DNI_1, :LLICENCIA_1, :NOM_1, :COGNOM1_1, :COGNOM2_1, :CODIUCI_1;

UPDATE CU0001
SET LLICENCIA=:LLICENCIA_1, NOM=:NOM_1, COGNOM1=:COGNOM1_1, COGNOM2=:COGNOM2_1, CODIUCI=:CODIUCI_1
WHERE DNI= : DNI_1;
end

jafera
02-12-2011, 18:52:55
Gracias Casimiro.

Tampoco funciona quitando begin suspend y end

Sigo investigando, me queda un acueducto por delante y debe cundir para mucho

Saludos

Casimiro Notevi
02-12-2011, 19:02:04
¿Pero el error sale compilándolo?

guillotmarc
02-12-2011, 20:03:39
Hola xiquet, para hacer un bucle poniendo los datos de una consulta en unas variables, tienes que utilizar una construcción FOR SELECT.


begin

FOR SELECT C11, C10, C5, C6, C7, C13
FROM CU0001E
INTO :DNI_1, :LLICENCIA_1, :NOM_1, :COGNOM1_1, :COGNOM2_1, :CODIUCI_1
DO BEGIN

UPDATE CU0001 SET
LLICENCIA=:LLICENCIA_1,
NOM=:NOM_1,
COGNOM1=:COGNOM1_1,
COGNOM2=:COGNOM2_1,
CODIUCI=:CODIUCI_1
WHERE DNI = :DNI_1;

SUSPEND;

END

end

Salut

jafera
02-12-2011, 20:32:29
Gracias a los dos, me habeis pillado en la carretera camino de casa.

Antonio, no me da error de compilación, solo de parámetros.

Marc, lo pruebo y comento.

Saludos

jafera
02-12-2011, 20:38:07
Marc, probado y me lanza el mismo error en ejecución

"Required Param Value Not Set"

No se que mirar, no se si en el componente IBStoreProc hay que modificar algo.

Si lo ejecuto en IBExpert, se queda como pidiendome los valores, en output parameters no hay nada y si voy a la pestaña sql me dice

EXECUTE PROCEDURE ACTUALITZA_RFEC('', '', '', '', '')

Gracias

Josep

Casimiro Notevi
02-12-2011, 21:11:42
¿Pero qué parámetros le pasas y cómo?

duilioisola
02-12-2011, 21:33:24
Parece un problema con los componentes de base de datos Delphi.
Yo creo que no cargas los parámetros antes de llamar a ExecProc.
No se qué componentes utilizas pero debería ser algo así:


with F_ModulDades.Actualitza_RFEC
do
begin
Close;
Params.ByName['LLICENCIA'].AsString := 'A123';
Params.ByName['NOM'].AsString := 'JUAN';
Params.ByName['COGNOM1'].AsString := 'PEREZ';
Params.ByName['COGNOM2'].AsString := 'GOMEZ';
Params.ByName['CODIUCI'].AsString := 'C1234';
ExecProc;
end;

jafera
02-12-2011, 21:38:03
Utilizo los componentes IBX.

No se, igual estoy equivocado pero, no se realiza el proceso directamente en el Firebird?

Porque sino, pasarle los parametros desde delphi si solo es un registro ok pero si son mas de 30.000 registros a actualizar......

Gracias

guillotmarc
02-12-2011, 21:48:13
Hola Josep.

Es que has definido las variables de Licencia, Nombre, Apellidos, ... como parámetros de entrada. Por eso esta esperando que se los pases. En lugar de ello, defínelas solo como variables.

NOTA: También he eliminado el SUSPEND, puesto que creí que las variables eran de salida y realmente querías obtener esos datos en Delphi.


SET TERM ^ ;

CREATE PROCEDURE "ACTUALITZA_RFEC"
AS
declare variable dni varchar(12) character set iso8859_1;
declare variable llicencia varchar(14) character set iso8859_1;
declare variable nom varchar(20) character set iso8859_1;
declare variable cognom1 varchar(25) character set iso8859_1;
declare variable cognom2 varchar(25) character set iso8859_1;
declare variable codiuci varchar(12) character set iso8859_1;
begin
FOR SELECT C11, C10, C5, C6, C7, C13
FROM CU0001E
INTO :DNI, :LLICENCIA, :NOM, :COGNOM1, :COGNOM2, :CODIUCI
DO BEGIN

UPDATE CU0001 SET
LLICENCIA=:LLICENCIA,
NOM=:NOM,
COGNOM1=:COGNOM1,
COGNOM2=:COGNOM2,
CODIUCI=:CODIUCI
WHERE DNI = :DNI;

SUSPEND;

END
end
^

SET TERM ; ^


Salut.

jafera
02-12-2011, 22:04:54
Gracias Marc, eres mi Angel de la Guardia.

En IBExpert funciona bien (el proceso se hace en segundos, cuando antes tardaba muchos..... minutos), pero desde Delphi me sigue lanzando el mismo error de parametro.

Josep

Casimiro Notevi
02-12-2011, 22:07:19
Repito: ;)
¿Pero qué parámetros le pasas y cómo?

guillotmarc
02-12-2011, 22:20:31
És un plaer. :)

Como dice Casimiro, el problema debe venir en como llamas al procedimiento almacenado en Delphi. Si nos enseñas ese código, probablemente te podamos ayudar.

Pero, como dice el dicho : para este viaje no hacen falta alforjas.

Lo que quieres hacer se consigue con esta simple consulta :


UPDATE CU0001 SET
LLICENCIA = (SELECT C10 FROM CU0001E WHERE C11 = DNI),
NOM = (SELECT C5 FROM CU0001E WHERE C11 = DNI),
COGNOM1 = (SELECT C6 FROM CU0001E WHERE C11 = DNI),
COGNOM2 = (SELECT C7 FROM CU0001E WHERE C11 = DNI),
CODIUCI = (SELECT C13 FROM CU0001E WHERE C11 = DNI)
WHERE EXISTS (SELECT * FROM CU0001E WHERE C11 = DNI)


NOTA: Asegúrate de tener en CU0001E un índice para C11, y verás como se ejecuta en un tiempo récord. :)

Salut.

jafera
02-12-2011, 22:23:44
Hola Casimiro.

Lo que hago es lo que esta puesto en el SP, nada más cargo los datos de una tabla y los copio en la otra.

No le paso ningun parametro más que el de DNI=: DNI

Igual olvido algun paso, no se, como he dicho antes es mi primera vez con los SP

Gracias

Josep

guillotmarc
02-12-2011, 22:37:52
Hola Casimiro.

Lo que hago es lo que esta puesto en el SP, nada más cargo los datos de una tabla y los copio en la otra.

No le paso ningun parametro más que el de DNI=: DNI

Igual olvido algun paso, no se, como he dicho antes es mi primera vez con los SP

Gracias

Josep

Josep, elimina el componente en tu programa y vuelve a ponerlo (probablemente aún conserva la definición de parámetros que tenía inicialmente el SP).

No le tienes que pasar ningún parámetro, ni siquiera el DNI, puesto que hemos hecho el SP sin parámetros.

Si sigue fallando, copianos el código Delphi exacto que utilizas, para que le podamos echar una ojeada.

NOTA: En un mensaje anterior te he puesto una consulta que hará el mismo trabajo, ligeramente más rápido incluso, que el SP.

Salut.

jafera
02-12-2011, 23:21:44
De nuevo apurado.

Esta consulta update, se pone con un componente consulta normal?

Es que al hacer mencion a dos tablas....

Estoy ofuscado, creo que cierro y me voy a tomar un cocacola a ver si me despejo

Hasta luego

Casimiro Notevi
03-12-2011, 09:52:32
Cuando vuelvas, lee tranquilamente lo que te hemos contestado antes ;)

jafera
03-12-2011, 11:38:03
Gracias Casimiro.

Lo he leido, releido y vuelto a leer.

El SP ya funciona, lo que no acabo de ver como (y seguro que es lo mas simple del mundo), es el tema de la consulta que lea de una tabla y actualize otra.

Lo que he utilizado como update siempre han sido parametros o actualizar un campo (UPDATE TABLA SET CAMPO = 'S'), pero, lo siento, mi nivel de sql no llega a más.

Yo soy vendedor de barcos y uso Delphi como un hobby no es mi "modus vivendi".

Cada vez que me he conectado a este foro siempre he recibido buenas respuestas, alguna vez incluso he contestado yo algun post porque era algo que habia utilizado y sabia como hacerlo.

Bueno pues no más "ladrillo" seguiré investigando y buscando mas informacion acerca de como hacer el update marcado.

Saludos mañadiles-sabadiles, aunque estoy en el currete a ver si engaño a alguien y le coloco el Queen Mary II.

Josep

Casimiro Notevi
03-12-2011, 12:38:15
Pon aquí tu código, verás que pronto lo resolvemos :)

Por cierto, ¿vendedor de barcos?, ¿de qué tipo de barcos?, yo estoy soñando con un velero (los catamaranes son demasiado caros) y es un tema que me apasiona, ¿quién sabe?, lo mismo te cambio un store procedure por un velero :)

jafera
03-12-2011, 14:28:02
Buenas

Como he dicho antes, el SP ya me funciona, hace exactamente lo que quiero, quite el componente y lo puse de nuevo y ya no me da el error de parametros.

Lo que yo decía es que no se como ejecutar la consulta Update que me proponía Marc,


UPDATE CU0001 SET
LLICENCIA = (SELECT C10 FROM CU0001E WHERE C11 = DNI),
NOM = (SELECT C5 FROM CU0001E WHERE C11 = DNI),
COGNOM1 = (SELECT C6 FROM CU0001E WHERE C11 = DNI),
COGNOM2 = (SELECT C7 FROM CU0001E WHERE C11 = DNI),
CODIUCI = (SELECT C13 FROM CU0001E WHERE C11 = DNI)
WHERE EXISTS (SELECT * FROM CU0001E WHERE C11 = DNI)


no se que componente debo usar ni como hacer referencia a las dos tablas para hacer el update, con un select * busco todos los campos pero el update supongo lo debo hacer por parametros, sino no veo la manera. Estoy seguro de que es una solución simple pero no doy con ella, en cuanto le vea el cu.. seguro que digo que es gallina.

En cuanto al velero pues ya sabes, no te lo puedo cambiar por un SP porque yo no soy el dueño y no llego a tanto aunque aun te debería dinero ya que es mas caro un buen SP que funcione bien que un velero.

Saludos

Casimiro Notevi
03-12-2011, 16:20:58
Sólo tienes que ejecutarlo con cualquier dataset, pones algo así como:
execute procedure CU0001

guillotmarc
03-12-2011, 19:55:07
Bona tarda, Josep.

Buenas

Como he dicho antes, el SP ya me funciona, hace exactamente lo que quiero, quite el componente y lo puse de nuevo y ya no me da el error de parametros.

Lo que yo decía es que no se como ejecutar la consulta Update que me proponía Marc,

Código SQL [-] (http://www.clubdelphi.com/foros/#) UPDATE CU0001 SET LLICENCIA = (SELECT C10 FROM CU0001E WHERE C11 = DNI), NOM = (SELECT C5 FROM CU0001E WHERE C11 = DNI), COGNOM1 = (SELECT C6 FROM CU0001E WHERE C11 = DNI), COGNOM2 = (SELECT C7 FROM CU0001E WHERE C11 = DNI), CODIUCI = (SELECT C13 FROM CU0001E WHERE C11 = DNI) WHERE EXISTS (SELECT * FROM CU0001E WHERE C11 = DNI)


no se que componente debo usar ni como hacer referencia a las dos tablas para hacer el update, con un select * busco todos los campos pero el update supongo lo debo hacer por parametros, sino no veo la manera. Estoy seguro de que es una solución simple pero no doy con ella, en cuanto le vea el cu.. seguro que digo que es gallina.

En cuanto al velero pues ya sabes, no te lo puedo cambiar por un SP porque yo no soy el dueño y no llego a tanto aunque aun te debería dinero ya que es mas caro un buen SP que funcione bien que un velero.

Saludos

Para ejecutar esa consulta lo puedes hacer con un objeto IBQuery normal y corriente, como cualquier otra consulta. No te preocupes porqué utilice dos tablas, a eso se le llama subconsultas, es decir consultas dentro de una consulta. Pero el conjunto forma una única consulta.

Lo único que hay que tener en cuenta, es que como toda consulta UPDATE (o INSERT, DELETE, ...) no devuelve ningún resultado, por lo tanto en lugar de ejecutarla con un .Open, la debes ejecutar con un .ExecSQL.

Salut.

jafera
04-12-2011, 20:17:27
Hola a todos.

Mil millones de gracias.

Ahora si lo veo claro, como dije ayer cuando le ves el cu.. dices que es gallina; A veces nos ofuscamos con cosas que a la postre son siemples (cuando se tienen por mano jejejeje).

He intentado el execsql y me da error de "column unknow DNI at line 2, column 50" como si no le gustase el = DNI.

Olvido algo?

Gracias por vuestro tiempo, sois unos cracks y unos F1, (help, no coche), de emergencia cojon..o, profesores, confesores, etc.

Que no decaiga nunca el foro.

Saludos

Josep

guillotmarc
04-12-2011, 22:30:34
Entonces pruébalo así.

UPDATE CU0001 SET
LLICENCIA = (SELECT C10 FROM CU0001E WHERE C11 = CU0001.DNI),
NOM = (SELECT C5 FROM CU0001E WHERE C11 = CU0001.DNI),
COGNOM1 = (SELECT C6 FROM CU0001E WHERE C11 = CU0001.DNI),
COGNOM2 = (SELECT C7 FROM CU0001E WHERE C11 = CU0001.DNI),
CODIUCI = (SELECT C13 FROM CU0001E WHERE C11 = CU0001.DNI)
WHERE EXISTS (SELECT * FROM CU0001E WHERE C11 = CU0001.DNI)

Salut.