PDA

Ver la Versión Completa : ¿insertar en procedimientos ?


Giniromero
20-02-2004, 14:36:17
Hola,

Estoy trabajando con delphi 6 e interbase 7.

Tengo un procedimiento en IB, que llamo desde mi programa, con un tDataSet, rellenando el EditSQL.

Puedo "Añadir campos" desde el "Editor de campos", pero si desde el "DataSet Editor" genero SQL para insertar, modificar, ... me da error de código SQL al intentar añadir campos nuevos.

La única forma que conozco para que me permita insertar esos campos, es dándole código SQL a la insercción , (insertSQL), pero o no lo hago bien, o no se puede insertar en estos procedimientos.

¿Alguien puede ayudarme con esto?, por que, por lo que tengo leido en el foro, veo que los procedimientos dentro de interbase, son muy comunmente usados, y me imajino que tiene que tener alguna forma de usarlos para insertar registros nuevos.

Gracias

Virginia

__cadetill
20-02-2004, 15:18:50
Si he entendido bien, estás utilizando el TIBDataSet para hacer llamadas a un Procedimiento Almacenado???

Si es así, no estás utilizando el componente correcto, has de usar el TIBStoredProc

Giniromero
20-02-2004, 16:12:19
Glups! ya sabía yo que tenía que estar haciendo algo mal...
:o :D :eek: , no hay nada en esta vida como "saber".

Supongo que se usará más o menos igual, ¿no?....

Bueno, pos' lo dicho, que muchas gracias....

Virginia

Giniromero
20-02-2004, 17:41:36
Hola,
He usado el TIBStoredProc en vez del tibDataSet, y al compilar el programa me resuelve el siguiente error, cuando se está abriendo la base de datos,

"Use ExecProc for Procedure : use TQuery for Select procedures"

supongo que hay algo más que debo saber al respecto de los TIBStoredProc, como por ejemplo, como les pido que se abran, si es que hay que pedirselo.

GRacias,

Virginia

Nuria
20-02-2004, 18:47:33
Hola Giniromero!

1.- Tienes que enlazar el TIBStoredProc con una transacción.

2.- Cuando quieras ejecutar el procedimiento : (transaccion --> tr; TIBStoredProc---> IBP)

tr.Active := False;
IBP.StoredProcName := nombredelprocedimiento;

if not tr.InTransaction then
tr.StartTransaction;

// Si tuvieras que enviarle algun parámetro
IBP.ParamByName('Parametro').AsInteger := Para;
IBP.ExecProc;
tr.Commit;


No sé si me he explicado bien. ;)

Saludos!

kinobi
21-02-2004, 09:03:50
Hola,

como es un asunto de componentes de acceso, muevo el hilo desde "InterBase y Firerbird" a "Conexión con bases de datos".

Saludos.

Giniromero
23-02-2004, 12:37:55
Perdonar mi torpeza, pero, ......

1) ¿tengo que "abrir" el StoredPRoc, como con las tablas, esto es:

IBStoredPRoc.Active := True;?


2) En la ayuda que tengo de Ib me dicen que tengo que usar "prepare" para el IBStoredPRoc.

Después dentro de un try lo ejecutarlo con ExecProc
y en el finally le hago un "unprepare" para liberar los recursos que este estuviera usando.

Ahora, me comentais que ...




tr.Active := False;
IBP.StoredProcName := nombredelprocedimiento;

if not tr.InTransaction then
tr.StartTransaction;

// Si tuvieras que enviarle algun parámetro
IBP.ParamByName('Parametro').AsInteger := Para;
IBP.ExecProc;
tr.Commit;




Me podríais, si no es mucha molestia, explicar para que sirbe, y como usar, cada uno de estos comandos relaccionados con el IBStoredPRoc? Por que me estoy haciendo un lío, y no parece que consigua hacerlo funcionar.

Muchas gracias por todo,


Virginia

__cadetill
23-02-2004, 12:54:21
A ver, un IBStoredProc tienes que planteartelo "como si fuera" una TIBQuery con parámetros. Es decir, a un procedimiento almacenado, tu puedes pasarle parámetros si los necesitas (que puedes definirlos en la propiedad Params del mismo), que es lo que te comenta Nuria con lo de

BP.ParamByName('Parametro').AsInteger := Para;


Por otro lado, un TIBStoredProc no "se abre", sino que se ejecuta

BP.ExecProc;


Y por supuesto ha de ir dentro de una transacción

Nuria
23-02-2004, 12:55:23
1) ¿tengo que "abrir" el StoredPRoc, como con las tablas, esto es:

IBStoredPRoc.Active := True;?


No, porque el IBStoredProc lo tienes enlazado con una transacción, lo que realmente activas es la transacción.


2) En la ayuda que tengo de Ib me dicen que tengo que usar "prepare" para el IBStoredPRoc.


Yo no lo uso y me funciona correctamente. Quizá es recomendable usarlo no sé.

Por que me estoy haciendo un lío, y no parece que consigua hacerlo funcionar.

Porque no pones parte del código para ver si hay algo que haces mal.

Saludos!

Giniromero
24-02-2004, 10:56:50
Hola,

este es mi código:


screen.cursor := crHourGlass;
FrmEfePago := TFrmEfePago.Create(Self);
Screen.cursor := crDefault;

FrmDModule.TbEconoPago.Prepare;
TRY
FrmDModule.IBTransFXProce.Active := false;

if not FrmDModule.IBTransFXProce.InTransaction then begin
FrmDModule.IBTransFXProce.StartTransaction;
end;
FrmDModule.TbEconoPago.ParamByName('numalu').AsInteger := FrmDModule.TbAlumnosNUMALU.AsInteger;
FrmDModule.TbEconoPago.ExecProc;
//si NO hay registros de deudas
// if FrmDmodule.TbEconoPago.RecordCount = 0 then begin
// showmessage('No existen efectos a pagar !!!');
// end
// else begin // Si hay registros de deudas
//inserta un registro
FrmDmodule.TbEcono.Append;
//mostramos como modal el form
FrmEfePago.ShowModal;
// end;

FrmDMOdule.IBTransFXProce.Commit;
FINALLY

FrmEfePago.Free;
//liberamos recursos usados con el Procedure
FrmDMOdule.TbEconoPago.UnPrepare;
END;


Si quito el comentario del " if FrmDmodule.TbEconoPago.RecordCount = 0 then " me responde siempre que 'No existen efectos a pagar !!!'

Si lo comento, al menos me deja entrar en la ventana en cuestión, pero este procedimiento está conectado con un DBgrid, que no muestra nada, asíque parece como si ni siquiera se llegase a abrir el procedimento.

hay algo que se me esté escapando?

GRacias por la ayuda.

Virginia

Nuria
24-02-2004, 11:30:02
Hola Giniromero!

Una sugerencia, has probado el procedimiento por el ibConsole o algún programa similar, igual lo que te falla es el procedimiento. Haz la comprobación desde ahí a ver si te devuelve registros.

Podías indicar el código del procedimiento.

Saludos!

Giniromero
24-02-2004, 12:40:14
Hola Nuria,

El procedimiento funciona perfectamente desde IBExpert, que es, de hecho, donde lo he creado. Me devuelve 300 registros más o menos que son los pendientes de pago.

Por ahí no hay ningún problema.

El tema es que no sé como abrir el procedimiento desde la aplicación.

Te cuento lo que tengo, para ver si me falta algo.

Tengo un procedure creado en IB, (usando IBExpert), que tiene el siguiente código:


CREATE PROCEDURE PROECONOPAGO (
NUMALUACT SMALLINT)
RETURNS (
CODIGO INTEGER,
NUMALU SMALLINT,
NUMGRUP SMALLINT,
FECHA TIMESTAMP,
ASIENTO INTEGER,
CONCEPTO VARCHAR(50),
IMPDEBE NUMERIC(15,2),
IMPHABER NUMERIC(15,2),
FORPAGO SMALLINT,
RECIBO VARCHAR(10),
FACTURA VARCHAR(10),
USUARIO VARCHAR(10),
TIPO VARCHAR(1),
EMPRESATXT VARCHAR(1),
CONTROL VARCHAR(1))
AS
DECLARE VARIABLE VCODIGO INTEGER;
DECLARE VARIABLE VNUMALU SMALLINT;
DECLARE VARIABLE VNUMGRUP SMALLINT;
DECLARE VARIABLE VFECHA TIMESTAMP;
DECLARE VARIABLE VASIENTO INTEGER;
DECLARE VARIABLE VCONCEPTO VARCHAR(50);
DECLARE VARIABLE VIMPDEBE NUMERIC(15,2);
DECLARE VARIABLE VIMPHABER NUMERIC(15,2);
DECLARE VARIABLE VFORPAGO SMALLINT;
DECLARE VARIABLE VRECIBO VARCHAR(10);
DECLARE VARIABLE VFACTURA VARCHAR(10);
DECLARE VARIABLE VUSUARIO VARCHAR(10);
DECLARE VARIABLE VTIPO VARCHAR(1);
DECLARE VARIABLE VPRODUCTOGRUP VARCHAR(2);
DECLARE VARIABLE VEMPRESAPRO VARCHAR(1);
begin
for select CODIGO, NUMALU, NUMGRUP, FECHA, ASIENTO, CONCEPTO, IMPDEBE,
IMPHABER, FORPAGO, RECIBO, FACTURA, USUARIO, TIPO

from ECONO
WHERE NUMALU =:NUMALUACT
order by numalu
into
:VCODIGO,:VNUMALU,:VNUMGRUP,:VFECHA,:VASIENTO,:VCONCEPTO,:VIMPDEBE,
:VIMPHABER, :VFORPAGO,:VRECIBO,:VFACTURA,:VUSUARIO,:VTIPO do
begin
select PRODUCTO from grupos where NUMGRUP =:vnumgrup into :vproductogrup ;
select EMPRESA from produ where PRODUCTO=:vproductogrup into :vempresapro;

If (:vasiento <2 AND :vimpdebe <> 0 ) Then Begin
CODIGO = :VCODIGO;
NUMALU = :VNUMALU;
NUMGRUP = :VNUMGRUP;
FECHA = :VFECHA;
ASIENTO = :VASIENTO;
CONCEPTO = :VCONCEPTO;
IMPDEBE = :VIMPDEBE;
IMPHABER = :VIMPHABER;
FORPAGO = :VFORPAGO;
RECIBO = :VRECIBO;
FACTURA = :VFACTURA;
USUARIO = :VUSUARIO;
TIPO = :VTIPO;
EMPRESATXT =:vempresapro;
suspend;
end
end
end



Luego, en mi aplicación, (usando delphi 6 e interbase 7), dentro de un DataModule, tengo un TIbStorePro, conectado a una transaccion que solo le afecta a el, conectada a la base de datos general.

El TIBStorePRo tiene las siguientes propiedades:



object TbEconoPago: TIBStoredProc
Database = IBDBFX
Transaction = IBTransFXProce
OnCalcFields = TbEconoPagoCalcFields
OnNewRecord = TbEconoPagoNewRecord
StoredProcName = 'PROECONOPAGO'
Left = 282
Top = 80
ParamData = <
item
DataType = ftInteger
Name = 'CODIGO'
ParamType = ptOutput
end
item
DataType = ftSmallint
Name = 'NUMALU'
ParamType = ptOutput
end
item
DataType = ftSmallint
Name = 'NUMGRUP'
ParamType = ptOutput
end
item
DataType = ftDateTime
Name = 'FECHA'
ParamType = ptOutput
end
item
DataType = ftInteger
Name = 'ASIENTO'
ParamType = ptOutput
end
item
DataType = ftString
Name = 'CONCEPTO'
ParamType = ptOutput
end
item
DataType = ftBCD
Name = 'IMPDEBE'
ParamType = ptOutput
end
item
DataType = ftBCD
Name = 'IMPHABER'
ParamType = ptOutput
end
item
DataType = ftSmallint
Name = 'FORPAGO'
ParamType = ptOutput
end
item
DataType = ftString
Name = 'RECIBO'
ParamType = ptOutput
end
item
DataType = ftString
Name = 'FACTURA'
ParamType = ptOutput
end
item
DataType = ftString
Name = 'USUARIO'
ParamType = ptOutput
end
item
DataType = ftString
Name = 'TIPO'
ParamType = ptOutput
end
item
DataType = ftString
Name = 'EMPRESATXT'
ParamType = ptOutput
end
item
DataType = ftString
Name = 'CONTROL'
ParamType = ptOutput
item
DataType = ftSmallint
Name = 'NUMALUACT'
ParamType = ptInput
end

end>
object TbEconoPagoCODIGO: TIntegerField
FieldName = 'CODIGO'
Origin = 'PROECONOPAGO.CODIGO'
end
object TbEconoPagoNUMALU: TSmallintField
FieldName = 'NUMALU'
Origin = 'PROECONOPAGO.NUMALU'
end
object TbEconoPagoNUMGRUP: TSmallintField
FieldName = 'NUMGRUP'
Origin = 'PROECONOPAGO.NUMGRUP'
end
object TbEconoPagoFECHA: TDateTimeField
FieldName = 'FECHA'
Origin = 'PROECONOPAGO.FECHA'
end
object TbEconoPagoASIENTO: TIntegerField
FieldName = 'ASIENTO'
Origin = 'PROECONOPAGO.ASIENTO'
end
object TbEconoPagoCONCEPTO: TIBStringField
FieldName = 'CONCEPTO'
Origin = 'PROECONOPAGO.CONCEPTO'
Size = 50
end
object TbEconoPagoIMPDEBE: TIBBCDField
FieldName = 'IMPDEBE'
Origin = 'PROECONOPAGO.IMPDEBE'
Precision = 18
Size = 2
end
object TbEconoPagoIMPHABER: TIBBCDField
FieldName = 'IMPHABER'
Origin = 'PROECONOPAGO.IMPHABER'
Precision = 18
Size = 2
end
object TbEconoPagoFORPAGO: TSmallintField
FieldName = 'FORPAGO'
Origin = 'PROECONOPAGO.FORPAGO'
end
object TbEconoPagoRECIBO: TIBStringField
FieldName = 'RECIBO'
Origin = 'PROECONOPAGO.RECIBO'
Size = 10
end
object TbEconoPagoFACTURA: TIBStringField
FieldName = 'FACTURA'
Origin = 'PROECONOPAGO.FACTURA'
Size = 10
end
object TbEconoPagoUSUARIO: TIBStringField
FieldName = 'USUARIO'
Origin = 'PROECONOPAGO.USUARIO'
Size = 10
end
object TbEconoPagoTIPO: TIBStringField
FieldName = 'TIPO'
Origin = 'PROECONOPAGO.TIPO'
Size = 1
end
object TbEconoPagoEMPRESATXT: TIBStringField
FieldName = 'EMPRESATXT'
Origin = 'PROECONOPAGO.EMPRESATXT'
Size = 1
end
object TbEconoPagoCONTROL: TIBStringField
FieldName = 'CONTROL'
Origin = 'PROECONOPAGO.CONTROL'
Size = 1
end
object TbEconoPagoNUMALUACT: TSmallintField
FieldName = 'NUMALUACT'
Origin = 'PROECONOPAGO.NUMALUACT'
Size = 1
end

end




Este TIbStoreProc tiene un DataSource enlazado a él.

Este DataSource está relacionado con el DBGrid de la ventana en la que quiero se muestren los registros de los apunte económicos pendientes de pago, que, como te comenté antes, salen vacios, como si no lo ejecutase.

El código que utilizo para abrir este procedimiento es:



screen.cursor := crHourGlass;
FrmEfePago := TFrmEfePago.Create(Self);
Screen.cursor := crDefault;


TRY
FrmDMOdule.IBTransFXProce.Active := false;

if not FrmDModule.IBTransFXProce.InTransaction then begin
FrmDModule.IBTransFXProce.StartTransaction;
end;
FrmDModule.TbEconoPago.ParamByName('numaluACT').AsInteger := FrmDModule.TbAlumnosNUMALU.AsInteger;
FrmDModule.TbEconoPago.Prepare;
FrmDMOdule.IBTransFXProce.Active := true;
FrmDModule.TbEconoPago.ExecProc;
//si NO hay registros de deudas
if FrmDmodule.TbEconoPago.RecordCount = 0 then begin
showmessage('No existen efectos a pagar !!!');
end
else begin // Si hay registros de deudas
//inserta un registro
FrmDmodule.TbEcono.Append;
//mostramos como modal el form
FrmEfePago.ShowModal;
end;

FrmDMOdule.IBTransFXProce.Commit;
FINALLY

FrmEfePago.Free;
//liberamos recursos usados con el Procedure
FrmDMOdule.TbEconoPago.UnPrepare;

END;




Muchas gracias por la ayuda,

Virginia

__cadetill
24-02-2004, 12:51:14
Hola Virginia

Quizás este hilo (http://www.clubdelphi.com/foros/showthread.php?t=7546) te sirva de guía para lo que quieres hacer

Giniromero
24-02-2004, 13:46:10
Gracias Cadetill,

La construcción de procedimientos, en mi caso no es
maravillosa, pues no tengo mucha esperiencia, pero
funciona ok, con sus parámentros de entrada, de salida,...
pero hay algo que no entiendo, a pesar de haber leido el
hilo que me apuntaste.

Para llamar al procedimiento desde el programa, ¿no
puedo usar el TIbStorePRoc?, tengo que hacerlo desde otro
tipo de conexión? por que la verdad, yo estaba usando
TbDataSet, pero una de las cosas que me interesan, es
poder guardar registros nuevos a través de ese
procedimiento, vamos, que no sea sólo "lectura", y esta es
la razón por la que me pasé a usar TIBStoreProc.


Probé a conectar un TIbDataSet, cuando no se le insertaba
parámetros de entrada, y se abría y se mostraban los
datos en el dbgrid, pero esa opción no me vale, pues,
como ya dige ante, tengo que poder insertar registros
nuevos, y usando el TIBDataSet no se puede.

De todos modos, creo que no he entendido bien lo que le
están recomendando en ese hilo.

por que ese de:

utilizar procedimientos para filtrar una tabla (o una join
sobre varias tablas) no es el procedimiento habitual ni el
recomendado, para eso tienes la cláusula WHERE.



¿Que quiere decir esto? ¿para que se puede usar entonces?
pues, o no lo he entendido bien, o me descoloca la idea
que tenía de los procedimientos.

Muchas gracias por la ayuda,

Virginia

Nuria
24-02-2004, 16:47:07
Hola Virginia!


FrmDModule.TbEconoPago.ParamByName('numaluACT').AsInteger := FrmDModule.TbAlumnosNUMALU.AsInteger;


Has hecho una parada para ver que valor le estas mandando al procedimiento, ya que me comentabas que siempre te salía 'No existen efectos a pagar !!!' . Es una sugerencia porque no sé donde te puede estar fallando, te lo seguiré mirando.

Saludos!

Giniromero
24-02-2004, 17:13:35
Hola a tod@s,


he vuelto a mirarme lo que pone en "developer's guide" respecto de los procedimientos, y ahora si que no sé que pensar.

Por un lado vosotros me comentais que no hay que poner el TIBStoredProc.Active := True;

por otro lado leo que:

"For Stored procedures that return a cursor, use the active property or the open method"

Además, veo como el mismo procedimiento, (sin parametros input), que estoy utilizando, me muestra los registros en el dbgrid, cuando uso un dataset para mostrarlos, pero no parece abrirse cuando ese mismo procedure lo intento mostrar en el mismo DBgrid, usando un tIBStoredProc.

Es como si no se abriese, de hecho, tengo que ejecutar una inserción despues de mostrar el form con el dbgrid que tendría que mostrarme los registros, y al ir a hacer dicha insercción, me dice que la tabla esta cerrada.

Por favor, ¿alguien podría ponerme un ejemplo, de uso de este objeto o decirme como hacer?

Estoy empantanada mientras no lo consigua poner en marcha.



Muchas gracias por vuestra ayuda,

Virginia

:confused: :confused: :confused:

Giniromero
24-02-2004, 19:34:05
Hola Nuria,


Le estoy pasando el valor del alumno que está actualmente activo.
El "FrmDModule.TbAlumnosNUMALU.AsInteger;"
aparentemente funciona ok. Si le digo que :

showmessage (FrmDModule.TbAlumnosNUMALU.asstring);

efectivamente me devuelve el valor del alumno activo.

De todos modos, eso es lo de menos, por que tambiem me da problemas si hago que no aparezca esa variable ni en el servidor de bD, ni en la aplicación.

Creo sinceramente, que el problema es que NO se está abriendo el procedimiento o que no stoy usando bien el TIBStoredProc.

¿ha usando alguien alguna vez el TIbStoredProc para mostrar registros que devuelve en un DBgrid?

Por que es eso, básicamente lo que necesito.

En tal caso, ¿como lo abría/ponía en funcionamiento, vamos, como mostrar en ese DBGrid, los datos que, por lo menos me muestra sin problemas en el IBExpert cuando ejecuto este procedimiento?

Gracias a todos por la ayuda,

Virginia

guillotmarc
24-02-2004, 20:03:48
Hola.

En dbExpress no se puede abrir un SP, si devuelve datos, para abrirlos en un dataset tienes que usar un Query y lanzar una consulta del tipo :

select * from Procedimiento(:Parametro)

Imagino que en IBX es parecido.

Giniromero
25-02-2004, 09:47:43
Hola,


En dbExpress no se puede abrir un SP, si devuelve datos, para abrirlos en un dataset tienes que usar un Query y lanzar una consulta del tipo :

select * from Procedimiento(:Parametro)



Una vez más disculpaz por mi torpeza, pero :

"¿si devuelve datos? "

Pensaba que todos los procedimientos, de un modo u otro, devolvían datos. ¿Te refieres a si devuelve registros?, ¿hay procedimientos que no devuelvan ningún dato?


"¿para abrirlos en un dataset tienes que usar un Query y lanzar una consulta?"

A ver que me aclare. ¿Tengo que usar un dataSet en el que ponga, dentro de la propiedad del SelectSQL, código como el que tu me pasas?, ¿A que te refieres con lanzar una consulta?
y con eso, ¿podré insertar registros usando ese DataSet?, entonces, ¿cuando se usa el TIBStoredPRoc?

Muchas gracias por vuestra paciencia y ayuda.

Virginia

Nuria
25-02-2004, 10:02:00
Hola!

No había caido, Marc tiene razón. en los IBX es igual.

En el IBDataSet en la propiedad SelectSQL : select * from Procedimiento(:Parametro) y funciona perfectamente, creo que en tú caso deberías ponerlo en la propiedad InsertSQL, nunca he usado esta propiedad con procedimientos, pero supongo que no será problema.


¿cuando se usa el TIBStoredPRoc?


Lo puedes utilizar, cuando por ejemplo, tengas que hacer un procedimiento, nunca mejor dicho, que se repite muchas veces , como calcular totales,ect.
Ejecutas el TIBStoredProc.

No se si me explicado bien... :rolleyes:

__cadetill
25-02-2004, 10:09:57
De lo que no estoy seguro es de que los datos que devuelva un SP sean también de escritura (yo diría que no, pero no lo aseguro). Si estubiera en lo cierto, con un TIBQuery tienes más que suficiente para tus menesteres

guillotmarc
25-02-2004, 10:34:38
Hola.

Para complementar lo que han dicho los compañeros, solo comentar que un procedimiento que devuelve datos (selectable stored proc), es aquel que devuelve un conjunto de filas (como una consulta o una vista). Se utilizan cuando tienes que realizar una consulta muy compleja que no puedes condensar en una sentencia SELECT.

Los procedimientos almacenados que no devuelven datos, són aquellos que realizan una acción, como por ejemplo tu caso en que insertan un registro, es decir un procedimiento que ejecuta sentencias del tipo INSERT INTO, ...

En el primer caso es cuando hay que leer los datos devueltos, abriendo una consulta con un select * from PROCEDIMIENTO, en el segundo caso es cuando se ejecuta un procedimiento mediante un IBStoredProc.

Saludos.
Saludos.

Giniromero
26-02-2004, 13:21:57
Tengo un TIBDataSet, (TbEconoPago), que tiene:



object TbEconoPago: TIBDataSet
Database = IBDBFX
Transaction = IBTransFX
OnCalcFields = TbEconoPago1CalcFields

//si ASIENTO tiene valor 1 es por que hemos seleccionado ese asiento
//para que sea pagado, por lo que le ponemos una X en el campo de CONTROL
IF FrmDModule.TbEconoPagoASIENTO.Value = 1 THEN BEGIN
FrmDModule.TbEconoPagoCONTROL.Value := 'X';
END
ELSE BEGIN
//si el ASIENTO no tiene valor 1, es por que no lo hemos seleccionado
//para pagarlo
FrmDModule.TbEconoPagoCONTROL.Value := '';
END;


OnNewRecord = TbEconoPago1NewRecord

TbEconoPagoIMPHABER.Value := 0;
TbEconoPagoIMPDEBE.Value := 0;
//le inserto la fecha actual
TbEconoPagoFECHA.Value := date;
TbEconoPagoUSUARIO.Value := TbUsersUSUARIO.Value;
TbEconoPagoNUMALU.Value := TbAlumnosNUMALU.Value;
TbEconoPagoNUMGRUP.Value := 0;



BufferChunks = 1000
CachedUpdates = False
DeleteSQL.Strings = (
//NADA
'')
InsertSQL.Strings = (
insert into ECONO
(CODIGO, NUMALU, NUMGRUP, FECHA, CONCEPTO, IMPDEBE, IMPHABER, FORPAGO, RECIBO, FACTURA, USUARIO, TIPO) values
(:CODIGO, :NUMALU, :NUMGRUP, :FECHA, :CONCEPTO, :IMPDEBE, :IMPHABER, :FORPAGO, :RECIBO, :FACTURA, :USUARIO, :TIPO))

SelectSQL.Strings = (
select CODIGO, NUMALU, NUMGRUP, FECHA, CONCEPTO, IMPDEBE,
IMPHABER, FORPAGO, RECIBO, FACTURA, USUARIO, TIPO, ASIENTO
from PROECONOPAGO
where numalu=:numalu
order by fecha desc)


ModifySQL.Strings = (
update ECONO
set
CODIGO = :CODIGO,
NUMALU = :NUMALU,
NUMGRUP = :NUMGRUP,
FECHA = :FECHA,
CONCEPTO = :CONCEPTO,
IMPDEBE = :IMPDEBE,
IMPHABER = :IMPHABER,
FORPAGO = :FORPAGO,
RECIBO = :RECIBO,
FACTURA = :FACTURA,
USUARIO = :USUARIO,
TIPO = :TIPO
where
CODIGO = :OLD_CODIGO
)
DataSource = SrcAlumnos
Left = 40
Top = 392
object TbEconoPagoCODIGO: TIntegerField
FieldName = 'CODIGO'
Origin = 'PROECONOPAGO.CODIGO'
end
object TbEconoPagoNUMALU: TSmallintField
FieldName = 'NUMALU'
Origin = 'PROECONOPAGO.NUMALU'
end
object TbEconoPagoNUMGRUP: TSmallintField
FieldName = 'NUMGRUP'
Origin = 'PROECONOPAGO.NUMGRUP'
end
object TbEconoPagoFECHA: TDateTimeField
FieldName = 'FECHA'
Origin = 'PROECONOPAGO.FECHA'
end
object TbEconoPagoCONCEPTO: TIBStringField
FieldName = 'CONCEPTO'
Origin = 'PROECONOPAGO.CONCEPTO'
Size = 50
end
object TbEconoPagoIMPDEBE: TIBBCDField
FieldName = 'IMPDEBE'
Origin = 'PROECONOPAGO.IMPDEBE'
Precision = 18
Size = 2
end
object TbEconoPagoIMPHABER: TIBBCDField
FieldName = 'IMPHABER'
Origin = 'PROECONOPAGO.IMPHABER'
Precision = 18
Size = 2
end
object TbEconoPagoFORPAGO: TSmallintField
FieldName = 'FORPAGO'
Origin = 'PROECONOPAGO.FORPAGO'
end
object TbEconoPagoRECIBO: TIBStringField
FieldName = 'RECIBO'
Origin = 'PROECONOPAGO.RECIBO'
Size = 10
end
object TbEconoPagoFACTURA: TIBStringField
FieldName = 'FACTURA'
Origin = 'PROECONOPAGO.FACTURA'
Size = 10
end
object TbEconoPagoUSUARIO: TIBStringField
FieldName = 'USUARIO'
Origin = 'PROECONOPAGO.USUARIO'
Size = 10
end
object TbEconoPagoTIPO: TIBStringField
FieldName = 'TIPO'
Origin = 'PROECONOPAGO.TIPO'
Size = 1
end
object TbEconoPagoASIENTO: TIntegerField
FieldName = 'ASIENTO'
Origin = 'PROECONOPAGO.ASIENTO'
end
object TbEconoPagocontrol: TStringField
FieldKind = fkCalculated
FieldName = 'control'
Size = 1
Calculated = True
end
end



Mi procedimiento almacenado es el siguiente:


CREATE PROCEDURE PROECONOPAGO
RETURNS (
CODIGO INTEGER,
NUMALU SMALLINT,
NUMGRUP SMALLINT,
FECHA TIMESTAMP,
ASIENTO INTEGER,
CONCEPTO VARCHAR(50),
IMPDEBE NUMERIC(15,2),
IMPHABER NUMERIC(15,2),
FORPAGO SMALLINT,
RECIBO VARCHAR(10),
FACTURA VARCHAR(10),
USUARIO VARCHAR(10),
TIPO VARCHAR(1),
EMPRESATXT VARCHAR(1),
CONTROL VARCHAR(1))
AS
DECLARE VARIABLE VCODIGO INTEGER;
DECLARE VARIABLE VNUMALU SMALLINT;
DECLARE VARIABLE VNUMGRUP SMALLINT;
DECLARE VARIABLE VFECHA TIMESTAMP;
DECLARE VARIABLE VASIENTO INTEGER;
DECLARE VARIABLE VCONCEPTO VARCHAR(50);
DECLARE VARIABLE VIMPDEBE NUMERIC(15,2);
DECLARE VARIABLE VIMPHABER NUMERIC(15,2);
DECLARE VARIABLE VFORPAGO SMALLINT;
DECLARE VARIABLE VRECIBO VARCHAR(10);
DECLARE VARIABLE VFACTURA VARCHAR(10);
DECLARE VARIABLE VUSUARIO VARCHAR(10);
DECLARE VARIABLE VTIPO VARCHAR(1);
DECLARE VARIABLE VPRODUCTOGRUP VARCHAR(2);
DECLARE VARIABLE VEMPRESAPRO VARCHAR(1);
DECLARE VARIABLE VCONTROL VARCHAR(1);
begin
for select CODIGO, NUMALU, NUMGRUP, FECHA, ASIENTO, CONCEPTO, IMPDEBE,
IMPHABER, FORPAGO, RECIBO, FACTURA, USUARIO, TIPO

from ECONO

order by numalu
into
:VCODIGO,:VNUMALU,:VNUMGRUP,:VFECHA,:VASIENTO,:VCONCEPTO,:VIMPDEBE,
:VIMPHABER, :VFORPAGO,:VRECIBO,:VFACTURA,:VUSUARIO,:VTIPO do
begin
select PRODUCTO from grupos where NUMGRUP =:vnumgrup into :vproductogrup ;
select EMPRESA from produ where PRODUCTO=:vproductogrup into :vempresapro;

If (:vasiento <2 AND :vimpdebe <> 0 ) Then Begin

CODIGO = :VCODIGO;
NUMALU = :VNUMALU;
NUMGRUP = :VNUMGRUP;
FECHA = :VFECHA;
ASIENTO = :VASIENTO;
CONCEPTO = :VCONCEPTO;
IMPDEBE = :VIMPDEBE;
IMPHABER = :VIMPHABER;
FORPAGO = :VFORPAGO;
RECIBO = :VRECIBO;
FACTURA = :VFACTURA;
USUARIO = :VUSUARIO;
TIPO = :VTIPO;
EMPRESATXT = :vempresapro;
CONTROL = :vcontrol;
suspend;
end
end
end


El problema es que no creo que sea muy ortodoxo tomar los datos de un procedimiento y pedir que guarde registros en una tabla. Me imagino que estos procedimientos tienen que tener una forma más apropiada de insertar registros.
Además, aunque así me muestra los datos en el DBGrid, tarda mucho en abrirse el form en el que está ese dbgrid.

Por otro lado, la aplicación me va mucho más lenta cuando tengo este TIBDataSet conectado a mi procedimiento almacenado. O un TIBStoredPRoc, parece que le cuesta cada vez que se tiene que abrir. ¿es eso normal?
Me he vuelto a leer todo lo que me habéis escrito en este hilo, así como el que cadetill me aconsejo leer, y tengo dudas, (como no). Sigo sin Saber muy bien como se usan / tratan los procedimintos almacenados a través del delphi.

Esto es:

1) ¿Tengo que tener, por un lado, un TIBStoredProc, enlazado con una transacción, al cual tendré que ejecutar, cada vez que quiera que recalcule los campos a mostrar, (usando para ellos el .ExecProc;). Y por otro lado, un query o tibdataset, donde seleccionar ese procedimiento almacenado, sus campos, etc... para mostrarlo en el DBGrid?

2) ¿qué tengo que hacer cada vez que quiera mostrar los datos, registros, resultantes del procedimiento almacenado?, ¿ejecutar primero el procedimiento con el execproc, cerrando y abriendo la transacción a la que está conectado?

3) Según esto:

Para complementar lo que han dicho los compañeros, solo comentar que un procedimiento que devuelve datos (selectable stored proc), es aquel que devuelve un conjunto de filas (como una consulta o una vista). Se utilizan cuando tienes que realizar una consulta muy compleja que no puedes condensar en una sentencia SELECT.

Los procedimientos almacenados que no devuelven datos, són aquellos que realizan una acción, como por ejemplo tu caso en que insertan un registro, es decir un procedimiento que ejecuta sentencias del tipo INSERT INTO, ...

En el primer caso es cuando hay que leer los datos devueltos, abriendo una consulta con un select * from PROCEDIMIENTO, en el segundo caso es cuando se ejecuta un procedimiento mediante un IBStoredProc.

¿Tengo que tener dos procedimientos almacenados, uno para tomar los datos usando el ibdataset y otro para insertar datos, usando el ibStoredProc?

De antemano, gracias a tod@s por la ayuda,

Virginia