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)
-   -   Realizar un Update con MDO (https://www.clubdelphi.com/foros/showthread.php?t=43876)

FGarcia 23-05-2007 00:27:18

Realizar un Update con MDO
 
Hola!
Pues la consulta de este dia es que no se que esta mal al realizar una actualizacion de un registro modificado.

Esta es la descripcion del script que se genero en un componente MDODataset:

Código Delphi [-]
UPDATE DPPUSR
SET
  CODIGO = :CODIGO,
  LOGIN = :LOGIN,
  CLAVE = :CLAVE,
  CATEGORIA = :CATEGORIA,
  NOMBRE = :NOMBRE,
  PATERNO = :PATERNO,
  MATERNO = :MATERNO,
  DOMICILIO = :DOMICILIO,
  COLONIA = :COLONIA,
  CP = :CP,
  CIUDAD = :CIUDAD,
  ESTADO = :ESTADO,
  RFC = :RFC,
  CURP = :CURP,
  IFE = :IFE,
  TELEFONO = :TELEFONO
WHERE
  CODIGO = :OLD_CODIGO

y esta es la manera en que le estoy insertando o actualizando datos:

Código Delphi [-]
procedure TfrmUsers.btnGuardarClick(Sender: TObject);
var
    sContra : String;
    i: integer;
begin
    btnGuardar.SetFocus;
 
    if VerificaDatos then
      begin
        with frmDatos.MDOUsers    do
          begin
            
            sContra := frmDatos.Encripta(edClave.Text);
            if cbCategoria.text = 'Instalador' then
              i := 1
            else if cbCategoria.text = 'Supervisor' then
              i := 2
            else
              i := 3;
 
            if sModo = 'Insertar' then
              begin
                Insert;
                FieldByName('Login').Value := Trim(edLogin.text);
                FieldByName('Clave').Value := sContra;
                FieldByName('Categoria').Value := i;
                FieldByName('Nombre').Value := Trim( edNombre.text);
                FieldByName('Paterno').Value := Trim(edPaterno.text);
                FieldByName('Materno').Value := Trim(edMaterno.text);
                FieldByName('Domicilio').Value := Trim(edDomicilio.text);
                FieldByName('Colonia').Value := Trim(edColonia.text);
                FieldByName('CP').Value := Trim(edCP.text);
                FieldByName('Ciudad').Value := Trim(edCiudad.text);
                FieldByName('Estado').Value := Trim(edEstado.text);
                FieldByName('Telefono').Value := Trim(edTelefono.text);
                Post;
                
                iClave := FieldByName('clave').AsInteger;
                lstUsuarios.Items.Add(edLogin.Text)
              end
            else
              begin
                Edit;
                FieldByName('Codigo').Value := iClave; //Clave Primaria
                FieldByName('Login').Value := Trim(edLogin.text);
                FieldByName('Clave').Value := sContra;
                FieldByName('Categoria').Value := i;
                FieldByName('Nombre').Value := Trim( edNombre.text);
                FieldByName('Paterno').Value := Trim(edPaterno.text);
                FieldByName('Materno').Value := Trim(edMaterno.text);
                FieldByName('Domicilio').Value := Trim(edDomicilio.text);
                FieldByName('Colonia').Value := Trim(edColonia.text);
                FieldByName('CP').Value := Trim(edCP.text);
                FieldByName('Ciudad').Value := Trim(edCiudad.text);
                FieldByName('Estado').Value := Trim(edEstado.text);
                FieldByName('Telefono').Value := Trim(edTelefono.text);
                Post;
              end;
          end;
      end;
      btnCancelarClick(Sender);
end;

Hasta el codigo de Insertar todo va bien se realiza correctamente. Sin embargo la actualizacion no, me aparece el error de violacion de la clave primaria

---------------------------
Contveh
---------------------------
violation of PRIMARY or UNIQUE KEY constraint "PK_DPPUSR" on table "DPPUSR"
---------------------------
Aceptar
---------------------------

Lo cual entiendo es correcto, sin embargo no logro aterrizar la idea de como evitar eso.

Gracias por su ayuda!!!

Caral 23-05-2007 01:34:19

Hola
Asi de reojo:
aqui tienes unas variables
Código Delphi [-]
var
    sContra : String;  
    i: integer;
Aqui tienes una actualizacion que usa una de las variables:
Código Delphi [-]
  FieldByName('Clave').Value := sContra;
aqui se declara algo?
Código Delphi [-]
 iClave := FieldByName('clave').AsInteger;
Aqui tienes otra actualizacion:
Código Delphi [-]
 FieldByName('Codigo').Value := iClave;
Bueno me parece que es un integer?
Pero donde esta declarada.iClave ?, no lo veo.:confused:
Me ayudas a entenderlo?
Sañudos

sitrico 23-05-2007 02:58:54

Creo que tu problema esta por aqui:

Código Delphi [-]
                iClave := FieldByName('clave').AsInteger;
                lstUsuarios.Items.Add(edLogin.Text)
              end
            else
              begin
                Edit;
                FieldByName('Codigo').Value := iClave; //Clave Primaria

En el insert no asignas nigun valor a 'Codigo', yo para las claves primarias casi siempre uso un trigger de autoincremento

de lo contrario La línea:

Código Delphi [-]
FieldByName('Codigo').Value := iClave; //Clave Primaria

Debe estar tambien en el insert e iClave debe tener un valor unico

vtdeleon 23-05-2007 02:58:54

Saludos

Un pequeño ahorro en codigo
Código Delphi [-]
procedure TfrmUsers.btnGuardarClick(Sender: TObject);
var
    sContra : String;
    i: integer;
begin
    btnGuardar.SetFocus;
 
    if VerificaDatos then
      begin
        with frmDatos.MDOUsers    do
          begin
            
            sContra := frmDatos.Encripta(edClave.Text);
            if cbCategoria.text = 'Instalador' then
              i := 1
            else if cbCategoria.text = 'Supervisor' then
              i := 2
            else
              i := 3;
 
            if sModo = 'Insertar' then
              begin
                Insert;
                //Nos ahorramos todas esas lineas repetidas
              end
            else
              begin
                Edit;
                FieldByName('Codigo').Value := iClave; //Clave Primaria
              end;
              FieldByName('Login').Value := Trim(edLogin.text);
              FieldByName('Clave').Value := sContra;
              FieldByName('Categoria').Value := i;
              FieldByName('Nombre').Value := Trim( edNombre.text);
              FieldByName('Paterno').Value := Trim(edPaterno.text);
              FieldByName('Materno').Value := Trim(edMaterno.text);
              FieldByName('Domicilio').Value := Trim(edDomicilio.text);
              FieldByName('Colonia').Value := Trim(edColonia.text);
              FieldByName('CP').Value := Trim(edCP.text);
              FieldByName('Ciudad').Value := Trim(edCiudad.text);
              FieldByName('Estado').Value := Trim(edEstado.text);
              FieldByName('Telefono').Value := Trim(edTelefono.text);
              Post;
            if sModo = 'Insertar' then
              begin
                iClave := sContra;
                lstUsuarios.Items.Add(edLogin.Text)
              end

          end;
      end;
      btnCancelarClick(Sender);
end;

vtdeleon 23-05-2007 03:02:34

Ahora...

En la insercion asumo de que tienes algun contador que incremente el campo llave! Si no es asi, ahi ya tienes un error. Debes asegurarte de insertar un valor que no concida con ningun otro valor ya puesto anteriormente en ese campo, puesto que es un campo Primario y de valor Unico.

En la parte de modificar, no se para qué quieres modificar el campo llave o primario, no lo veo necesario. Obvia eso!

Saludos.

Caral 23-05-2007 04:11:25

Hola
Aqui esta parte de lo que yo comentaba, que faltaba:
Código Delphi [-]
 iClave := sContra;
Para mi hay que hacerle caso al maestro vtdeleon
Saludos

FGarcia 23-05-2007 06:48:13

Hola!

Efectivamente ya no registro el error que tenia anteriormente. Segui el codigo de vtdeleon y corrio el edit. Aun hay un error pero es de otro lado. Ya seguire dando lata!

Caral: es una Tontera la que hice (no solo aqui, sino en el codigo ) pero en realidad me dio flojera cambiarle el nombre a iClave el correcto hubiese sido "iCodigo" que es el campo de la clave primaria y es autoincrementable. De ahi la confusion, y ese valor lo cargo en otro procedimiento.

Gracias por la ayuda!!!!

FGarcia 13-06-2007 03:09:02

Ahora el error es al editar
 
¡Les cumplo la amenaza de regresar con este tema!

Resulta que el codigo ya me funciona para insertar sin embargo cuando edito, los campos editados NO se actualizan en el registro que tengo seleccionado. Se actualiza otro registro.

Yo tengo una lista (listBox) donde recupero de la BD los usuarios registrados. Cada vez que hago click sobre ella recupero los datos del usuario seleccionado. Si necesito modificar algo tengo un boton "Modificar" que habilita los text box necesarios. cuando hago click en el boton "Guardar" se ejecuta el codigo que ya se menciono anteriormente y que vtdeleon corrigio amablemente sin embargo como comente anteriormente se actualizan los campos del primer item del listbox. Entonces la conclusion es que antes de colocar el dataset en EDIT le debo de indicar el registro a modificar por medio de su Primary Key. ¿Eso como lo hago? ya que no puedo hacerlo despues de la sentencia EDIT pues al ser una clave primaria se violan las reglas de integridad.

Agradesco su ayuda.

FGarcia 14-06-2007 02:53:45

solucionado..........................
 
Bueno......

Como no vi demasiado interes en esto lo que hice fue cambiar mi codigo a esto:

Código Delphi [-]
//*******************************Boton de Guardar***********************//
procedure TfrmUsers.btnGuardarClick(Sender: TObject);
var
    sContra : String;
    i: integer;
begin
  //Con el dataset MDOUsers
    with frmDatos.MDOQuery1 do
      begin
        //Verifica que los campos login, contraseña y confirmacion no esten vacios
        if VerificaDatos then
          begin
            //Encriptamos la contraseña
            sContra := frmDatos.Encripta(edClave.Text);
            //Segun el item seleccionado en el Combo
            case cbCategoria.ItemIndex of
              1: i := 1; //'Instalador'
              2: i := 2; // Administrador
              3: i := 3; // Supervisor
              4: i := 4; // Usuario
            end;
            //Si estamos en el modo INSERTAR (Boton Agregar)
            if sModo = 'Insertar' then
              begin
                close;
                sql.Clear;
                sql.Add('INSERT INTO dppUSR (login,clave,categoria,nombre,');
                sql.Add('paterno,materno,domicilio,colonia,cp,ciudad,estado,');
                sql.Add('telefono) ');
                sql.add('VALUES(');
                sql.Add('''' + edLogin.Text + ''',''' + sContra + ''',');
                sql.add('''' + IntToStr(i) + ''', ''' + edNombre.text + ''',');
                sql.Add('''' + edPaterno.Text + ''',''' + edMaterno.Text+''',');
                sql.add('''' + edDomicilio.Text + ''','''+edColonia.Text+''',');
                sql.add('''' + edCP.Text + ''','''+ edCiudad.Text + ''',');
                sql.Add('''' + edEstado.Text + ''',''' + edTelefono.Text +''')');
                ExecSQL;
              end
            else
              begin
                close;
                sql.Clear;
                sql.Add('UPDATE dppUSR SET');
                sql.add('Login = ''' + edLogin.Text + ''',');
                sql.add('Clave = ''' + sContra + ''',');
                sql.add('Categoria = ''' + IntToStr(i) + ''',');
                sql.add('Nombre = ''' + edNombre.text + ''',');
                sql.add('Paterno = ''' + edPaterno.Text + ''',');
                sql.add('Materno = ''' + edMaterno.Text + ''',');
                sql.add('Domicilio = ''' + edDomicilio.Text + ''',');
                sql.add('Colonia = ''' + edColonia.Text + ''',');
                sql.add('CP = ''' + edCP.Text + ''',');
                sql.add('Ciudad = ''' + edCiudad.Text + ''',');
                sql.add('Estado = ''' + edEstado.Text + ''',');
                sql.add('Telefono = ''' + edTelefono.Text + '''');
                sql.Add(' WHERE Codigo = ''' + IntToStr(iCodigo) + '''');
                ExecSQL;
              end;
            //Añadimos a la lista de usuarios el nuevo miembro
            if sModo = 'Insertar' then
              lstUsuarios.Items.Add(edLogin.Text);
          end;
      btnCancelarClick(Sender);
      end;
end;

y pues sanseacabo el problema! cuando edito lo hace en el registro correcto, no protesta porque el campo login este declarado como UNIQUE y pues todos contentos!!!! .....


mmmmmm eso ultimo ni yo me lo crei! Insisto si la sentencia sql ya esta declarada en el "dataset editor" porque no me funciona correctamente o yo la estoy llamando en forma equivoca, algo que debere de continuar investigando pero por el momento ya resolvi mi problema y la aplicacion esta trabajando.

Delfino 14-06-2007 11:26:19

Código SQL [-]
 PATERNO = :PATERNO,
 MATERNO = :MATERNO,
 DOMICILIO = OMICILIO,
 COLONIA = :COLONIA,
 CP = :CP,
Aqui no hay error???

te faltan un D y dos puntos..

FGarcia 14-06-2007 17:42:34

no, no falta la d y los dos puntos, recuerda que las "caritas" se construyen a base de : y alguna letra D, P o similar y las etiquetas de codigo delphi no las discriminan.

Saludos!

Lepe 15-06-2007 14:17:45

Yo sigo viendo mucho código repetido.

Los MDO funcionan de lujo, por tanto, algo se está colando. Lo que yo hago es lo siguiente:

- Definir el GeneratorLink del MDODataset, esto es crucial para que no de fallos de clave primaria.
- En todas las sqls (incluida la de select) añado un parámetro para seleccionar solo el registro que me interesa.
- En el BeforePost, es donde asigno todos los Edits a sus respectivos campos.

Al final el código se reduce a:
Código Delphi [-]
  if modo = 'Insertar' then
   Insert
  else if modo = 'Modificar' then
   Edit;

Post;

PD: Sugiero que uses constantes o tipos enumerados, de lo contrario, tarde o temprano escribirás "modificar" en minúsculas y no entrará en esa condición, fallo que tardarás en descubrir, porque un fallo mecanográfico es lo último que piensas:
Código Delphi [-]
Type TModo = (mInsertar, mModificar);

if modo = mInsertar then 
....


La franja horaria es GMT +2. Ahora son las 14:25:17.

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