Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Procedimiento Almacenado UPDATE no se ejecuta (https://www.clubdelphi.com/foros/showthread.php?t=68090)

Rockin 24-05-2010 11:17:54

Procedimiento Almacenado UPDATE no se ejecuta
 
Buena a todos, escribo porque estoy desesperado, estoy fallando en algo pero no lo veo y he mirado en todos lados ya. Tengo varios procedimientos almacenados en mi BD Firebird los cuales me devuelven un conjunto de datos y funcionan perfectamente, el problema es cuando he creado el siguiente procedimiento para actualizar un registro:

Código SQL [-]
SET TERM ^ ;

CREATE PROCEDURE LOGIN_SUTIL(
  REF INTEGER)
AS
begin
UPDATE  SESION_POPUP
SET modificar = 0
where referencia =:REF;
END^

SET TERM ; ^

El procedimiento se ejecuta pero no modifica el registros, si alguien me puede echar una mano o ver donde está el fallo se lo agradecería.

Utilizo Firebird 2.1

Saludos y gracias de antemano.

kalimero 24-05-2010 11:47:48

Hola

Commit?

saludos

Rockin 24-05-2010 12:06:12

Hola, ¿donde pongo el commit?
Dentro del procedimiento, nunca he usado procedimeintos para actualizar registros y no lo tengo claro.

Saludos.

kalimero 24-05-2010 12:25:20

Hola.
Tienes que hacer el commit en el componente transaction que tengas asociado para ejecutar al procedimiento almacenado.

saludos

Casimiro Notevi 24-05-2010 12:28:09

¿Cómo usas el procedimiento?, ¿lo llamas desde delphi, desde otro procedimiento, trigger, etc?

Pon el código de cómo trabajas con él.



Edito: Debes hacer lo que indica kalimero

Rockin 24-05-2010 12:32:56

Lo estoy probando directamente desde el gestor de firebird (utilizo EMS Firebird Management), mi idea es llamarlo desde delphi, así desde el ClientDataSet:

Código Delphi [-]
with datDatos.CDSSesionPopup do
begin
                Close;
                CommandText:= 'execute procedure LOGIN_SUTIL (:ref)'                        
                Params.ParamByName('ref').AsInteger:= referencia;
                Execute;
end;

¿Es correcto?

Casimiro Notevi 24-05-2010 12:39:53

¿Qué es CDSSesionPopup?

Si es un algún tipo de dataset, entonces necesitas algo así como:

Código Delphi [-]
datDatos.CDSSesionPopup.close;
datDatos.CDSSesionPopup.CommandText:='execute procedure LOGIN_SUTIL (:ref)';
datDatos.CDSSesionPopup.Params.ParamByName('ref').AsInteger := referencia;
datDatos.CDSSesionPopup.Execute;
datDatos.CDSSesionPopup.Transaction.Commitretaining;

Rockin 24-05-2010 12:47:37

Es un ClientDataSet que accede a su DataSetProvider en el servidor de capa intermedia, no tiene la propiedad Transaction.

Casimiro Notevi 24-05-2010 12:50:58

Y vuelvo un poco atrás... ¿estás seguro que no modifica el registro?, o sea, si lo ejecutas manualmente desde ibexpert y le das a commit, ¿no se guarda?, eso quiere decir que no existe el registro con la referencia que has querido actualizar.

Rockin 24-05-2010 13:28:03

El registro existe porque lo estoy tomando directamente de la tabla, no obstante he probado con otros campos y tampoco los modifica.

Casimiro Notevi 24-05-2010 13:52:08

O sea, quieres decir que si abres el ibexpert y tecleas lo siguiente:

Código:

update sesion_popup
set modificar = 0
where referencia = 'XXX'

y le das al botón 'commit'... ¿no te actualiza el registro?

Se supone que XXX existe y está escrito igual (mayúsculas/minúsculas) y que el campo modificar tiene un valor distinto de cero.

Es que si es así... es imposible :)

Rockin 24-05-2010 13:54:21

Si, correcto, pero eso de imposible vamos a dejarlo, cosa más raras he visto.

Casimiro Notevi 24-05-2010 13:58:24

No, no, jejeje :) no podemos rendirnos tan rápido.

Veamos, qué tipo de campos son "modificar" y "referencia", varchar, char, integer, etc. ????

Rockin 24-05-2010 14:13:11

Vale, acabo de modificarlo desde el ibexpert sin problemas, pero desde el ClientDataSet no lo consigo, no se como mandarle el commit.

Casimiro Notevi 24-05-2010 14:58:49

Y el datasetprovider que usas supongo que está asociado a un componente de base de datos y el componente de base de datos estará asociado a un componente transaction.
La ruta sería esta:
datasetprovider.database.transaction.commit

guillotmarc 24-05-2010 17:43:33

El ClientDataset no es el componente más adecuado para ejecutar procedimientos almacenados de actualización.

Un ClientDataset es para mantener un conjunto de registros en memoria, modificarlos y devolverlos a la base de datos.

Los componentes que utilizas para el acceso a Firebird seguro que tienen un control adecuado para ejecutar procedimientos almacenados de actualización.

kalimero 24-05-2010 17:50:35

Hola.
Concluyendo ... Usa el TpFibStoredProc para ejecutar el procedimiento almacenado. A este componenente le asocias un TpFibTransaction que es al que le tienes quje hacer el commit o poner el TpFibStoredProc en autocomit.

Saludos

Rockin 25-05-2010 14:23:35

Hola, ya lo conseguí, ha sido un fallo de novato e inutil.

Tenia que implementar el commit en el servidor de capa intermedia en el evento AfterExecute de su datasetprovider, igual que tengo el AfterApplyUpdates.

El clientdataset sirve perfectamente para ejecutar procedimientos almacenados.

Gracias a todos.

guillotmarc 25-05-2010 16:25:00

Nadie dice que no sirva, pero nunca se diseñó para eso. Como el mismo nombre indica, el ClientDataset es para mantener un Dataset (conjunto de registros) en memoria, en la parte cliente de tu aplicación (y para actualizar sus modificaciones).

Solo tienes que leer lo que dice al respecto la documentación de Delphi :

Cita:

TClientDataset

TClientDataSet implements a database-independent dataset.

Unit

DBClient

Description

TClientDataSet represents an in-memory dataset. A client dataset can be used as

* A fully-functional, stand-alone, file-based dataset for single-tiered database applications. When used in this manner, the client dataset represents the data stored in a dedicated file on the user’s hard disk.

* A local in-memory buffer of the records from another dataset. The other (source) dataset can reside in the same form or data module as the client dataset (for example, when the client dataset provides navigation and editing support for the data from a unidirectional dataset). The source dataset can also reside on a separate system when the client dataset supports the client portion of a multi-tiered database application.

Note: The two functions described above are not mutually exclusive. An application can be designed to support the option of working with data offline, using the “briefcase” model. On site, the application uses TClientDataSet to communicate with the database server associated with a source dataset. When a user works off site, the client dataset writes a snapshot of the data to the hard disk. The application works with this snapshot off site, with the client dataset acting as a file-based dataset in a single-tiered application.

When a client dataset represents the data from another dataset, it communicates with that dataset through a dataset provider. The client dataset communicates with this provider through the IAppServer interface. When the provider is in the same form or data module as the client dataset, the IAppServer interface is implemented by a hidden object that is created for you. When used in a client application as part of a multi-tiered application, the client dataset passes all calls to the provider through a remote data module’s IAppServer interface.

No encontrarás la menor referencia a usar un ClientDataset para lanzar directamente consultas de actualización (ya vengan de procedimientos almacenados, consultas simples, ...). Repito, un ClientDataset es para mantener un Dataset en memoria.

Naturalmente puedes utilizarlo para otros menesteres, y hasta cabe la posibilidad de que incluso te funcione. Pero se trabaja mejor si utilizas la herramienta adecuada para cada tarea. Por ejemplo, matar mosquitos a cañonazos no siempre es buena idea, por divertido y atractivo que pueda parecer en un principio.

Rockin 25-05-2010 17:59:13

Dime otra manera de llamar a un procedimiento almacenado a través de mi Servidor de Capa Intermedia y si veo que es mejor que la que tengo la cambio sin problemas, siempre es bueno saber cosas nuevas y mejores.

Pero un clietdataset sirve para mas cosas que meter cosas en memoria, en un servidor de capa intermedia es el clientdataset quien interactura con el y manda los cambios a la BD, para eso tiene la propiedad commandtext, pero bueno, que cada uno haga lo que quiera.


La franja horaria es GMT +2. Ahora son las 19:37:49.

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