Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Actualizar un Registro Por SQL con varios parametros (https://www.clubdelphi.com/foros/showthread.php?t=92186)

Edwardfeliz 21-08-2017 05:32:43

Actualizar un Registro Por SQL con varios parametros
 
Saludos, y gracias por su atención.

Tengo una tabla "Cuotas" (Uso access), a la cual le quiero hacer un UPDATE por sql con un ADOQuery,
Quiero actualizar tres campos,
1- 'Fecha_Pago' que inicialmente esta vacío, "con la fecha actual"
2- 'Estado' con "realizado"
3- 'Mora' Con un valor numérico que esta en un edit, llamemoslo edit1

para encontrar el registro tomara en cuenta tres cosas, el campo 'NumPrestamo' que agrupa todos los registros relacionados a un préstamo, luego el campo 'Estado' que contiene el texto "Pendiente o Realizado" lo que quiere que solo tome en cuenta los registros que tengan "Pendiente" y por ultimo, 'Numero' que tiene el numero de la cuota, la cuestión es que quiero que seleccione el registro que tenga en este campo "Numero" el valor mas bajo, la idea es ir cambiando el registro en el orden ascendente cuando realizo cada UPDATE.

Por toda la explicación que he dado ya saben de que trata el programa, y se que la gran mayoria ha hecho esto o algo parecido.
soy otro novato buscando ayuda :D
Espero sus respuestas, Gracias.

Casimiro Notevi 21-08-2017 08:59:58

Tú mismo has descrito perfectamente la sentencia sql que hay que escribir, ya solamente te falta mirar cualquier tutorial sql :)
Y de esa manera dejarás de ser novato, porque si te la escribimos, entonces tú la copiarás y pegarás... y seguirás siendo novato toda la vida ;)
Y pregunta aquí mismo si tienes alguna duda.

Edwardfeliz 21-08-2017 14:29:54

Cita:

Empezado por Casimiro Notevi (Mensaje 520450)
Tú mismo has descrito perfectamente la sentencia sql que hay que escribir, ya solamente te falta mirar cualquier tutorial sql :)
Y de esa manera dejarás de ser novato, porque si te la escribimos, entonces tú la copiarás y pegarás... y seguirás siendo novato toda la vida ;)
Y pregunta aquí mismo si tienes alguna duda.

No concuerdo con usted señor Casimiro ;) , No soy esa clase de novato, Cada ves que pido ayuda aqui es porque no tengo ni idea de como resolverlo, y cuando se me ayuda copio el codigo en un txt y lo guardo, y los reciclo, ya lo intente, y no lo resolvi, lo volvere a escribir el codigo para subirlo aqui y ver si voy por el camino correcto. Y recuerda que para quien sabe la respuesta la solucion es muy simple.

Saludos :p

Casimiro Notevi 21-08-2017 16:48:02

Bien, pon tu código que lo vayamos viendo y ayudando.

Edwardfeliz 22-08-2017 03:11:41

Código Delphi [-]
Begin
 with QTemp do
    begin
    Close;
    SQL.Clear;
    SQL.Text:= 'UPDATE Cuotas SET Fecha_Pago = :Fecha, Estado = :Estado, Mora = :Mora  '+
               'Where (NumPrestamo =:Codigo) and (Numero =:Numero)';
    Parameters.ParamByName('Fecha').Value  := FormatDateTime('dd/mm/yyyy', Now);
    Parameters.ParamByName('Estado').Value := 'Realizado';
    Parameters.ParamByName('Mora').Value   := Edit1.Text;
    Parameters.ParamByName('Codigo').Value := EnumPrestamo.Text;
    Parameters.ParamByName('Numero').Value := ????
    ExecSQL;
    end;
 End;

Esto es lo que tengo hasta ahora, esta incompleto, como lo termino?

mallenat 22-08-2017 08:02:49

Yo lo resolvería por SQL, con una subselect. El valor de número vendria de:
Código SQL [-]
SELECT Min(Numero)
FROM Cuotas
WHERE NumPrestamo = :Codigo
*Sin conocer tu esquema de base de datos puede que en el where falte alguna condición. La idea es conseguir el mínimo número que te interese en esta select.

Si tu motor de base de datos admite subselects en un update lo puedes juntar:
Código SQL [-]
UPDATE Cuotas SET Fecha_Pago = :Fecha, Estado = :Estado, Mora = :Mora  
Where (NumPrestamo =:Codigo) and (Numero = (
    SELECT Min(Numero)
    FROM Cuotas
    WHERE NumPrestamo = :Codigo
))
En caso contrario deberías averiguar primero el mínimo y luego llamar a tu query.

Edwardfeliz 22-08-2017 14:32:29

en resumen tengo esto:
Código Delphi [-]
with QTemp do
    begin
    Close;
    SQL.Clear;
    SQL.Text:= 'UPDATE Cuotas SET Fecha_Pago =:Fecha, Estado = :Estado, Mora = :Mora '+
               'Where (NumPrestamo =:Codigo) and (Numero = (SELECT Min(Numero) '+
               'FROM Cuotas WHERE NumPrestamo = :Codigo))';
    Parameters.ParamByName('Fecha').Value  := FormatDateTime('dd/mm/yyyy', Now);
    Parameters.ParamByName('Estado').Value := 'Realizado';
    Parameters.ParamByName('Mora').Value   := Edit1.Text;
    Parameters.ParamByName('Codigo').Value := EnumPrestamo.Text;
    ExecSQL;
    end;

Pero estoy recibiendo el error de parametro "fecha" no encontrado.

AgustinOrtu 22-08-2017 17:36:34

Revisa el valor de la propiedad QTemp.Connection

Edwardfeliz 23-08-2017 01:06:30

El código no da error pero en la base de datos no pasa nada :confused:

Casimiro Notevi 23-08-2017 09:48:50

Abre el programa que uses para gestinar las bases de datos y ejecuta el sql desde allí, "juega" haciendo cambios para comprobar qué registros cumplen la condición.
Ahí no podemos ayudarte mucho si no podemos probar con tu base de datos.

Edwardfeliz 24-08-2017 01:33:49

Cita:

Empezado por Casimiro Notevi (Mensaje 520497)
Abre el programa que uses para gestinar las bases de datos y ejecuta el sql desde allí, "juega" haciendo cambios para comprobar qué registros cumplen la condición.
Ahí no podemos ayudarte mucho si no podemos probar con tu base de datos.

anexo la base de datos y los archivos delphi? para que hagan pruebas? :confused: :(

Edwardfeliz 24-08-2017 02:59:43

Solucion Temporal
 
Saludos, Yo de nuevo, fabrique una solución poco ortodoxa porque no se me ocurrió nada mas para resolver esto :confused:, si tienen alguna observación me gustaría saberla, Gracias.

Código Delphi [-]
Var
Cod, Numero : String;
Begin
 with QTemp do
    begin
    Close;
    SQL.Clear;
    SQL.Text:= 'SELECT TOP 1 Cod, Numero  FROM Cuotas WHERE (NumPrestamo =:Codigo) and (Estado = :Pendiente) '+
               'Order By Numero ASC';
    Parameters.ParamByName('Codigo').Value    := EnumPrestamo.Text;
    Parameters.ParamByName('Pendiente').Value := 'Pendiente';
    ExecSQL;
    Open;
    end;
 Cod   := Qtemp.FieldByName('Cod').AsVariant;
 Numero:= Qtemp.FieldByName('Numero').AsVariant;
 Begin
  with QTemp do
    begin
    Close;
    SQL.Clear;
    SQL.Text:= 'UPDATE Cuotas SET Fecha_Pago =:Fecha, Estado = :Estado, Mora = :Mora '+
               'Where Cod =:NumC';
    Parameters.ParamByName('Fecha').Value  := FormatDateTime('dd/mm/yyyy', Now);
    Parameters.ParamByName('Estado').Value := 'Realizado';
    Parameters.ParamByName('Mora').Value   := Edit1.Text;
    Parameters.ParamByName('NumC').Value   := Cod;
    ExecSQL;
    End;
 End;
End;;

Tuve que crear un campo autonumerico que denomine "Cod" para que tuviera un valor único y así luego poder hacer el UPTADE a ese único registro.
Cualquier sugerencia sera bien recibida.

Gracias.

Guti13 24-08-2017 09:33:41

Hola EdwardFeliz, la verdad es que no entiendo porque la sentencia con la subselect no te funcionaba a no ser que no existiera clave primaria en esa tabla, ya que en Access los updates con subselect no funcionan bien en estos casos. La opción que has tomado es buena, desde mi punto de vista toda tabla debe tener un campo de clave primaria única lo que si me salta a la vista es que en la consulta con subselect no tenías en cuenta que el estado fuera pendiente, sin embargo, en esta segunda versión si la tienes.

Edwardfeliz 24-08-2017 15:43:20

Cita:

Empezado por Guti13 (Mensaje 520517)
Hola EdwardFeliz, la verdad es que no entiendo porque la sentencia con la subselect no te funcionaba a no ser que no existiera clave primaria en esa tabla, ya que en Access los updates con subselect no funcionan bien en estos casos. La opción que has tomado es buena, desde mi punto de vista toda tabla debe tener un campo de clave primaria única lo que si me salta a la vista es que en la consulta con subselect no tenías en cuenta que el estado fuera pendiente, sin embargo, en esta segunda versión si la tienes.

Probe lo de la clave primaria y no hizo ninguna diferencia.

Y lo del "Estado" lo agregue ya que había logrado hacer el Update, lo vi necesario porque así daba mas detalles para especificar el registro a actualizar.

Casimiro Notevi 24-08-2017 18:31:09

Creo que necesitas reordenar tus ideas, y explicarnos claramente la situación, para que podamos ayudarte eficazmente.

Edwardfeliz 24-08-2017 18:49:40

Cita:

Empezado por Casimiro Notevi (Mensaje 520541)
Creo que necesitas reordenar tus ideas, y explicarnos claramente la situación, para que podamos ayudarte eficazmente.

El ultimo código que puse explica exactamente lo que quiero hacer, porque el código hace el trabajo, ¿Es la forma correcta de hacer el proceso? No lo se, ¿a que le llamo "correcto"? a que el método no de algún problema en el futuro o que si hay un método mejor como el SubSelect pero que sea funcional, seria lo indicado-

"la idea es actualizar la tabla cuotas, el update lo que hace es introducir la fecha de pago, cambiar el contenido del campo "Estado" (que por default esta "Pendiente") a realizado, y el campo "Mora" ser actualizacon con el contenido de un edit,

¿Como saber sobre cual registro hacer esto?
Va a Buscar en cuotas el registro que en el campo "NumPrestamo" contenga el numero del prestamo que esta en un edit, y el estado en "Pendiente", como esta consulta devuelve varios resultados iguales pero con la diferencia que existe otro campo que tiene el nombre "Numero" donde identifica el numero de la cuota (1,2,3,etc), va a elegir el registro que contenga el valor mas bajo en "Numero".

Saludos!

Casimiro Notevi 24-08-2017 18:57:29

Entonces lo indicado antes debe funcionar perfectamente:
Código SQL [-]
UPDATE Cuotas SET Fecha_Pago = :Fecha, Estado = :Estado, Mora = :Mora  
Where (NumPrestamo =:Codigo) and (Numero = (
    SELECT Min(Numero)
    FROM Cuotas
    WHERE NumPrestamo = :Codigo
))
Por lo que echa un vistazo a tu base de datos para encontrar el motivo de que no te funcione.
Imagino que access admitirá subselect, en caso contrario debería dar algún error, aunque tampoco es que me extrañara mucho que no lo acepte y que no avise.
La otra forma es hacerlo por separado, obtener primero el registro con el menor numero y luego actualizarlo.
Aunque no entiendo esto:
Cita:

Tuve que crear un campo autonumerico que denomine "Cod" para que tuviera un valor único y así luego poder hacer el UPTADE a ese único registro.
El registro debería tener siempre un "id" que lo diferencie de los demás registros.

Edwardfeliz 24-08-2017 19:05:40

Cita:

Empezado por Casimiro Notevi (Mensaje 520544)
Entonces lo indicado antes debe funcionar perfectamente:
Código SQL [-]
UPDATE Cuotas SET Fecha_Pago = :Fecha, Estado = :Estado, Mora = :Mora  
Where (NumPrestamo =:Codigo) and (Numero = (
    SELECT Min(Numero)
    FROM Cuotas
    WHERE NumPrestamo = :Codigo
))
Por lo que echa un vistazo a tu base de datos para encontrar el motivo de que no te funcione.
Imagino que access admitirá subselect, en caso contrario debería dar algún error, aunque tampoco es que me extrañara mucho que no lo acepte y que no avise.

Lo voy a volver a revisar (antes no encontré el problema) pero con los "Ojos frescos" buscare de nuevo.

Cita:

Empezado por Casimiro Notevi (Mensaje 520544)
La otra forma es hacerlo por separado, obtener primero el registro con el menor numero y luego actualizarlo.

Eso fue lo que hice anteriormente donde si "Funciona el codigo"


Cita:

Empezado por Casimiro Notevi (Mensaje 520544)
Aunque no entiendo esto: El registro debería tener siempre un "id" que lo diferencie de los demás registros.

Eso eso solo que en ves de ID le puse "Cod"


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

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