Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Uso del SQLUpdate (https://www.clubdelphi.com/foros/showthread.php?t=22829)

sitrico 28-06-2005 19:02:35

Uso del SQLUpdate
 
Estoy usando por primera vez un componente tUpdateSQL pero cuando trato de hacer cualquier actualización sobre la consulta me genera una excepción: "Table is Read Only".

Como hago para que las acciones de incluir, modificar y borrar se ejecuten?

Estas son las sentencias SQL en FormCreate:

a = tQuery y uSql = TUpdateSQL

Código Delphi [-]
 
With a do
   Begin
   SQL.Add('Select IdComp XXIdComp, IdAsiento XXIdAsiento, CodCta, Ref,
             Concepto, (Debe+Haber) Monto From '+NombreArch(NArchAsi));
   SQL.Add('Where IdComp = :IdComp');
   SQL.Add('Order By IdAsiento');
   ParamByName('IdComp').AsInteger := StrToInt(ValorClave);
   // Los Nombres de campo con XX delante son para ocultar 
   // las columnas en el DBGrid
   Open;
   End;
With uSql do
   Begin
   With InsertSQL do
      Begin
      Add('Insert Into '+NombreArch(NArchAsi));
      Add('(IdComp, CodCta, Ref, Concepto, Debe, Haber) Values');
      Add('(:IdComp, :CodCta, :Ref, :Concepto, :Debe, :Haber)');
      End;
   With ModifySQL do
      Begin
      Add('Update '+NombreArch(NArchAsi)+' Set');
      Add('CodCta = :CodCta, Ref= :Ref, Concepto = :Concepto,');
      Add('Debe = :Debe, Haber = :Haber');
      Add('Where IdComp = :IdComp And IdAsiento = :IdAsiento');
      End;
   With DeleteSQL do
      Begin
      Add('Delete From '+NombreArch(NArchAsi));
      Add('Where IdComp = :IdComp And IdAsiento = :IdAsiento');
      End;
   End;
Y para su funcionamiento defino en a.onUpdateRecord:
Código Delphi [-]
procedure TfActComprobantes.aUpdateRecord(DataSet: TDataSet;
  UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
begin
//  inherited;
Case UpdateKind of
   ukInsert : Begin
              a.ParamByName('IdComp').AsInteger := StrToInt(ValorClave);
              // Aqui deberán ir las asignaciones de los parámetros
              End;
   ukModify : Begin
              // Aqui deberán ir las asignaciones de los parámetros
              End;
   ukDelete : Begin // para probar sólo funciona borrar
              a.ParamByName('IdComp').AsInteger := StrToInt(ValorClave);
              a.ParamByName('IdAsiento').AsInteger := 
                              a.FieldByName('XXIdAsiento').AsInteger;
              End;
   End;
   Try
      uSql.Apply(UpdateKind);
      UpdateAction := uaApplied;
   Except
      UpdateAction := uaFail;
      End;
end;
y para Incluir Modificar o Borrar Uso algo así:

Código Delphi [-]
procedure TfActComprobantes.LaToolBar1aBorrarExecute(Sender: TObject);
begin
If MessageBoxStr('¿ Borrar el Asiento ?','Atención',MB_YesNo) = IdYes Then
   a.Delete;
end;
Al llegar a la línea a.delete se gerena el error

sitrico 29-06-2005 19:44:58

Ya resolví la primera parte del problema:

Hay que establecer la propiedad del TQuery

Código Delphi [-]
q.CachedUpdates := True;

y llamar al método

Código Delphi [-]
q.ApplyUpdates;

Para que se guarden los cambios.

Ahora la pregunta es:

¿ como puedo asignar los parametros del UpdateSQL ?

ya que al intentar aplicarlos al query me produce el error de parametro no encontrado y no encuentro ninguna otra forma de accesar a los parámetros

roman 29-06-2005 20:43:00

Primero que nada yo (punto de vista personal) evito usar hasta donde me es posible la componente UpdateSQL. Es para mí una de las cosas mas oscuras de la VCL.

A juzgar por la consulta SELECT que pones, no necesitas esta componente; basta que pongas la propiedad RequestLive del Query en true.

Ahora bien, los parámetros en las sentencias INSERT, UPDATE y DELETE de un UpdateSQL se llenan en automático, para lo cual es necesario que correspondan a nombres de columnas seleccionadas. Como en tu consulta SELECT usas alias (por una razón que no entiendo) entonces las sentencias del UpdateSQL imagino que deberían usar estos alias.

Por otro lado, en las sentencias UPDATE y DELETE, las cláusulas WHERE deberían usar los parámetros especiales OLD, por ejemplo:

Código SQL [-]
where
  IdComp = :OLD_IdComp and IdAsiento = :OLD_IdAsiento

Cuando se ejecuta el ApplyUpdates, estos parámetros especiales se sustituyen por los valores originales que había en el Query. Esto es lo que permite al UpdateSQL identificar al registro que debe actualizarse o borrarse.

Si realmente requieres el uso de esta componente te recomiendo que leas la ayuda de Delphi donde viene explicado. No digo bien explicado porque como dije, a mi juicio es de lo que peor explicado está en la ayuda. Aún así te servirá para tener una mejor idea de cómo usar la componente.

La ayuda menciona también que la componente tiene una propiedad Query, disponible sólamente por código, con la cual puedes sustituir manualmente los parámetros. Jamás la he usado y espero no tener nunca que hacerlo pero aparentemente sirve para esos casos en los que los nombres de los parámetros no coinciden con los nombres originales de los campos.

// Saludos

sitrico 30-06-2005 18:44:16

Bueno Roman, primero gracias, lo que estaba buscando era justo la propiedad Query del UpdateSQL para poder asignar MIS parametros a mano.

Pero tienes razón, el UpdateSQL es un objeto bastante "oscuro" y el funcionamiento no es muy predecible cuando la consulta difiere de

Select * from tabla

En fin. Cree un Query (QAct) normalito y 3 TStringList (Cada uno con las instrucciones para el Insert, Modify y Delete).

En el evento onUpdateRecord del Query de consulta (QAsi), asigno el TStringList correspondiente al UpdateKind pongo los parametros, lanzo ExecSQL y LISTO :confused:

Pues no, las actualizaciones se quedan en cache y al refrescar la Tabla regresa al estado original.

Si ejecuto un ApplyUpdates me genera la excepción 'Table is Read Only' aunque si guarda los cambios.

Tendrás alguna idea de lo que está pasando.

gama_blind 13-01-2007 05:50:37

disculpa en que evento invoco
updateSQL1.Apply(ukModify);

QUERY.ApplyUpdates;

suponiendo que inserte datos en un DBGrid y quiero que se apliquen los cambios en
la base de datos.?:confused:


La franja horaria es GMT +2. Ahora son las 17:24:04.

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