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)
-   -   Error: IBQuery: cannot modify a read-only dataset (https://www.clubdelphi.com/foros/showthread.php?t=77797)

agustinbus 27-02-2012 01:31:01

Error: IBQuery: cannot modify a read-only dataset
 
Hola como estan? estoy realizando una aplicacion con BD Firebird y utilizo los componentes IB.
Al tratar de insertar o modificar un registro me aparece el error:

IBQuery: cannot modify a read-only dataset

EDITO: El IBTransaction lo tengo en Read Commited


Espero puedan ayudarme en solucionarlo. Saludos!

ecfisa 27-02-2012 01:40:04

Hola agustinbus.

¿ Podrías poner la parte del código donde realizas la modificación o inserción ?

Saludos.

agustinbus 27-02-2012 01:53:02

Hola ecfisa! claro que si, gracias por responder tan rapidamente. En un boton tengo este codigo:

Código:

if fAddTable.Caption = 'Add table' then
    begin
      if (JvEdit1.Text = '') then
        begin
          MessageBox(handle,'Table ID field are required','Required fields',MB_OK);
        end
      else
        begin     
          Form1.QMesas.Open;
          Form1.QMesas.Insert;
          Form1.QMesasSECTOR.Value := Form1.QSectoresCODIGO.Value;
          Form1.QMesasESTADO.Value := 'READY';
          Form1.QMesasPERSONAS.Value := StrToInt(JvSpinEdit1.Text);
          Form1.QMesasCODIGO.Value := JvEdit1.Text;
          Form1.QMesasWIDTH.Value := 60;
          Form1.QMesasHEIGHT.Value := 60;
          Form1.QMesasLEFT.Value := 300;
          Form1.QMesasTOP.Value := 300;
          if RadioButton1.Checked = TRUE then
            begin
              Form1.QMesasFUMADOR.Value := RutaFumador;
            end
          else
            begin
              Form1.QMesasFUMADOR.Value := RutaNoFumador;
            end;
          Form1.QMesas.Post;
          fAddTable.Close;

Explico un poco mas del problema. Estaba realizando el proyecto en access pero decidi cambiar a firebird ya que no es una bd de escritorio como access, y es mas sencilla la distribucion del sistema.

Ese es el codigo que tenia ccuand hacia las inserciones en access, pero ahora siguiendo un poco el tutorial para novatos creado por caral(si bien recuerdo) coloque unIBDatabase enlazado a un IBTransaction y los IBQuery correspondientes con Datasources enlazados a ellos para poder mostrarlos en una grilla. La coneccion funciona correctamente pero al querer insertar un registro aparece el error.

ecfisa 27-02-2012 03:19:50

Hola agustinbus.

Si estas usando un TIBQuery, el uso más o menos sería así:
Código Delphi [-]
...
  with QMesas do
  begin
    Close;
    SQL.Clear;
    SQL.Add('INSERT INTO TU_TABLA (SECTOR,ESTADO,PERSONAS,CODIGO,WIDTH,HEIGHT,ALEFT,TOP)');
    SQL.Add('VALUES(:SEC,:EST,:PER,:COD,:WID,:HEI,:LEF,:TOP)');
    ParamByName('SEC').Value:=  Form1.QSectoresCODIGO.Value;
    ParamByName('EST').Value:=  'READY';
    ParamByName('PER').Value:=  StrToInt(JvSpinEdit1.Text);
    ParamByName('COD'.Value:=   JvEdit1.Text;
    ParamByName('WID').Value:=  60;
    ParamByName('HEI').Value:=  60;
    ParamByName('LEF').Value:=  300;
    ParamByName('TOP').Value:=  300;
    ExecSQL;
    Close;
  end;
end;
Donde "TU_TABLA" es el nombre de la tabla y el resto son los campos cuyos nombres y tipos intenté que correspondieran lo más posible con los tuyos.

Pero si te interesa trabajar en forma similar a un TTable con las ventajas de un TQuery con los componentes IBX yo usaría un TIBDataSet.

Un saludo.

agustinbus 28-02-2012 02:54:40

Muchas gracias por la respuesta, estube probando con una actualizacion y sale un error. Adapte tu codigo y busque en google como es la sintaxis de update. Pero me sale el siguiente error:

'Dynamic SQL Error SQL error code= -104
token unknown -line 1, column 55
LEFT'.


y despues de darle a continue me sale otro error:

'Unknown SQL data type (0)'.


el codigo que tengo es el siguiente:

Código:

with QMesas do
        begin
          Close;
          SQL.Clear;
          SQL.Add('UPDATE MESAS SET WIDTH = :WID, PERSONAS = :PER, HEIGHT = :HEI, LEFT = :LEF, TOP = :TO ');
          SQL.Add('WHERE CODIGO = :COD');
          ParamByName('WID').Value := ctrl.Width;
          ParamByName('HEI').Value := ctrl.Height;
          ParamByName('PER').Value := ctrl.Tag;
          ParamByName('LEF').Value := ctrl.Left;
          ParamByName('TO').Value := ctrl.Top;
          ParamByName('COD').Value := Form1.QMesasCODIGO.Value;
          ExecSQL;
          Open;
        end;


Si saco el campo LEFT de la sentencia SQL no sale ningun error, pero no realiza la actualizacion.

Espero puedas ayudarme. Saludos!

ecfisa 28-02-2012 03:57:44

Hola Agustín.
Cita:

'Dynamic SQL Error SQL error code= -104
token unknown -line 1, column 55
LEFT'.
Ese error te está diciendo que no existe un campo llamado "LEFT" en la tabla "MESAS".

En un principio me llamó la atención que la tabla "MESAS" que supongo almancena la cantidad de personas, el sector de ubicación, etc. de un grupo de mesas, tenga como nombres de campo a LEFT,WIDTH, HEIGHT, TOP...
Disculpame si te hago una pregunta tonta ¿ No estarás intentando darle las propiedades Left,Width,Height,Top de TControl al componente de datos TIBQuery ?

Aclararía mucho que nos dieras una brebe descripción sobre que almancenan los campos de la tabla "MESAS" (a que concepto corresponde lo que se guarda en TOP , LEFT o WIDTH por ejemplo )

Un saludo.

Casimiro Notevi 28-02-2012 11:02:53

También puede ser que confunda 'LEFT' con la palabra reservada 'LEFT JOIN'.

agustinbus 28-02-2012 15:52:41

Hola como estan! Les comento, esos campos los utilizo porque creo componentes en tiempo de ejecucion para hacer un mapa de las mesas y guardo el cada mesa su respectiva posicion y tamaños para poder cargarlos nuevamente en el mapa de mesas. El campo LEFT si existe en la tabla Mesas, tal vez el error este relacionado a lo que dice casimiro. Miren les dejo el codigo completo:


Código:

procedure TForm1.Action9Execute(Sender: TObject);
var
  CompName:String;
  comp : TComponent;
  ctrl : TControl;
begin
  QMesas.First;
  while not QMesas.Eof do
    begin

      CompName := QMesasCODIGO.Value;
      comp := Self.FindComponent(CompName);
      if Assigned(comp) then
        begin
          SelectOnRunTime1.SelectControl := TControl(comp);
          //SelectOnRunTime1.Selected := True;
          ctrl := SelectOnRunTime1.SelectControl;
        end;
      with QMesas do
        begin
          Close;
          SQL.Clear;
          SQL.Add('UPDATE MESAS SET WIDTH = :WID, PERSONAS = :PER, HEIGHT = :HEI, TOP = :TO ');
          SQL.Add('WHERE CODIGO = :COD');
          ParamByName('WID').Value := ctrl.Width;
          ParamByName('HEI').Value := ctrl.Height;
          ParamByName('PER').Value := ctrl.Tag;
          //ParamByName('LEF').Value := ctrl.Left;
          ParamByName('TO').Value := ctrl.Top;
          ParamByName('COD').Value := Form1.QMesasCODIGO.Value;
          ExecSQL;
          Open;
        end;
     
      QMesas.Next;
    end;

end;

Por otra parte, si saco el campo LEFT de la sentencia SQL no sale ningun error, pero no realiza la actualizacion.
Ahora probare cambiando el campo LEFT por otro en la tabla.
Saludos y muchas gracias por su tiempo!

agustinbus 28-02-2012 16:00:10

Miren que curioso esto, cambie los campos de la tabla mesas, y antes de hacer el commit en IBExpert me marca con color el campo LEFT y lo coloca entre comillas, seguro es una palabra reservada no?

agustinbus 28-02-2012 16:18:39

Realice los cambios en los campos de la tabla Mesas y cambie el codigo que quedo de la siguiente manera:

Código:

var
  CompName:String;
  comp : TComponent;
  ctrl : TControl;
begin
  QMesas.First;
  while not QMesas.Eof do
    begin

      CompName := QMesasCODIGO.Value;
      comp := Self.FindComponent(CompName);
      if Assigned(comp) then
        begin
          SelectOnRunTime1.SelectControl := TControl(comp);
          //SelectOnRunTime1.Selected := True;
          ctrl := SelectOnRunTime1.SelectControl;
        end;
      with QMesas do
        begin
          Close;
          SQL.Clear;
          SQL.Add('UPDATE MESAS SET ANCHO = :ANC, PERSONAS = :PER, ALTO = :ALT, ARRIBA = :ARR, IZQUIERDA = :IZQ ');
          SQL.Add('WHERE CODIGO = :COD');
          ParamByName('ANC').Value := ctrl.Width;
          ParamByName('ALT').Value := ctrl.Height;
          ParamByName('PER').Value := ctrl.Tag;
          ParamByName('IZQ').Value := ctrl.Left;
          ParamByName('ARR').Value := ctrl.Top;
          ParamByName('COD').Value := Form1.QMesasCODIGO.Value;
          ExecSQL;
          Open;
          Next;
        end;
    end;

Pero al realizar la actualizacion no se guardan los cambios. Firebird me esta dando dolores de cabeza! :confused: :(

ecfisa 28-02-2012 17:59:58

Hola Agustin.

Supongamos que tu tabla está declarada así:
Código SQL [-]
CREATE TABLE MESAS (
  CODIGO     CODIGO CHAR(6),
  ANCHO      INTEGER,
  PERSONAS   INTEGER,
  ALTO       INTEGER,
  ARRIBA     INTEGER,
  IZQUIERDA  INTEGER
);

Con este código tiene que modificar correctamente:
Código Delphi [-]
...
  with IBQuery1 do
  begin
    Close;
    SQL.Clear;
    SQL.Add('UPDATE MESAS SET ANCHO = :ANC, PERSONAS = :PER, ');
    SQL.Add('ALTO = :ALT, ARRIBA = :ARR, IZQUIERDA = :IZQ ');
    SQL.Add('WHERE CODIGO = :COD');
    ParamByName('ANC').Value := 100;
    ParamByName('ALT').Value := 100;
    ParamByName('PER').Value := 100;
    ParamByName('IZQ').Value := 100;
    ParamByName('ARR').Value := 100;
    ParamByName('COD').Value := '000001';
    ExecSQL;
  end;
...

Un saludo.

agustinbus 28-02-2012 18:19:13

Mi amigo Ecfisa, muchas gracias!, voy a guardar tu ejemplo en mi biblioteca de codigos. Cambie de componentes y ahora utilizo zeos, porque ellos me permiten realizar los insert y Updates con los metodos .Insert y .Edit que me resultan mas familiares.

Te agradezco mucho por darle una solucion a mi problema. Casimiro muchas gracias tambien!! :)

ecfisa 28-02-2012 18:37:39

Hola Agustín.

Me alegra que hayas solucionado el problema :).

Aunque no he usado los Zeos (escuché buenos comentarios sobre ellos), el componente TIBDataSet de los IBX como te comenté en el mensaje ( #4 ), también permite el uso de Insert, Edit, Post,...

Un saludo.

agustinbus 29-02-2012 16:54:43

Muchas gracias se me paso por alto! Saludos!


La franja horaria es GMT +2. Ahora son las 07:44:44.

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