Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Ayuda Locate (https://www.clubdelphi.com/foros/showthread.php?t=95983)

steelha 28-11-2022 15:37:46

Ayuda Locate
 
Buenas a todos. Estoy teniendo problema con un locate multiples campos. estoy buscando por dos condiciones que es el episodio y el codigo de items
la tabla es la siguiente:

Cita:

Table EpisItems
EpEpisodio bigint Unchecked
EpFecha char(10) Unchecked
Epiditems bigint Unchecked
EpPlantilla bigint Checked
EpValor text Checked
Código Delphi [-]
procedure TfrmPacientes.insomodvalor(codigo, paciente, medico: Integer;
  valor: string);
begin
  Dm.QryEpisodioItems.Close;
  DM.QryEpisodioItems.Open;
  if Dm.QryEpisodioItems.Locate('EpEpisodio;Epiditems',VarArrayOf([epinumero,codigo]),[]) then
      begin
        // Record found
        DM.QryEpisodioItems.Edit;
      end
  else
      begin
        // Record Not found
        DM.QryEpisodioItems.Insert;
        DM.QryEpisodioItemsEpEpisodio.Value := epinumero;
        DM.QryEpisodioItemsEpFecha.Value    := DateToStr(now);
        DM.QryEpisodioItemsEpPlantilla.Value:= DM.QryPlantillaDefaultidPlantilla.Value;
        DM.QryEpisodioItemsEpiditems.Value  := codigo;
      end;
  DM.QryEpisodioItemsEpValor.Value := valor;
  DM.QryEpisodioItems.Post;
  DM.QryEpisodioItems.Close;
end;

La cosa es que si el episodio y el ítem ya existe debería solo modificar el contenido del campo valor de lo contrario deberia insertar todos los campos. Pero de alguna forma siempre pasa por alto de que ya existe y lo intenta crear y de hay me da el error de primary key violation. Estuve buscando y no veo problema alguno en la sentencia: pero aun así no se que me estoy pasando por alto. Cualquier ayuda o comentario será bien acogido.

NOTA La tabla esta bajo SQL SERVER 2014 Delphi Xe7/10

PepCat 28-11-2022 15:55:07

Hola steelha,

¿Qué instrucción SQL ejecutas con la orden “DM.QryEpisodioItems.Open”?
¿Has comprado que al ejecutar la instrucción “DM.QryEpisodioItems.Open” aparezcan los registros que intentas buscar?

Por otra parte, creo que sería mucho más eficiente buscar directamente con SQL:
Código SQL [-]
SELECT FROM “nombre tabla” WHERE EpEpisodio = :epinumero AND Epiditems = :codigo

Neftali [Germán.Estévez] 28-11-2022 16:13:49

Cita:

Empezado por steelha (Mensaje 549426)
...Pero de alguna forma siempre pasa por alto de que ya existe y lo intenta crear y de hay me da el error de primary key violation.

¿Estás seguro de que los valores que pasas al Locate son "exactamente" iguales a los de la tabla (incluyendo mayúsculas y minúsculas)?
¿Si ejecutas el SQL Profiler de SQLServer ves la consulta? ¿Cual es?

steelha 28-11-2022 16:28:56

La sentencia es la siguiente
Código SQL [-]
SELECT *
FROM EpisItems
Where EpEpisodio = :epi

y los campos son valores enteros.

Coloque un showmessage para verificar que estuviese pasando valores y no ceros y en lo corrector me paso 5,84 el cual ya existe en la db pero aun asi paso a la parte de insertar como nuevo.

movorack 28-11-2022 17:07:34

Cita:

Empezado por steelha (Mensaje 549429)
y los campos son valores enteros.

Cita:

Empezado por steelha (Mensaje 549429)
..me paso 5,84 el cual ya existe en la db

Al fin! Son enteros o flotantes? :D

Si son flotantes, te comento:

Con Delphi muchas veces, he tenido problemas al manejarlos. Trato de no usarlos como llave o identificador de nada a menos que sea estrictamente necesario. Y mas cuando se almacenan en una DB. Ya que el valor decimal que calcula Delphi no es el mismo que obtienes del motor. Aunque en apariencia se vean igual.

Cita:

Empezado por Embarcadero
"What you see is not what you get"
Floating-point numbers written in the source code with decimal digits and floating-point numbers displayed on screen probably differ from what resides in memory. Do not assume that what you see on the console represents exactly what is in memory. Decimal to binary conversion (and back) cannot be done perfectly in every case.

Use integral, BCD, or Currency variables to avoid the IEEE floating-point representation error.

Link: https://docwiki.embarcadero.com/RADS...int_Arithmetic

steelha 28-11-2022 23:03:16

Cita:

Empezado por movorack (Mensaje 549430)
Al fin! Son enteros o flotantes? :D

Si son flotantes, te comento:

Con Delphi muchas veces, he tenido problemas al manejarlos. Trato de no usarlos como llave o identificador de nada a menos que sea estrictamente necesario. Y mas cuando se almacenan en una DB. Ya que el valor decimal que calcula Delphi no es el mismo que obtienes del motor. Aunque en apariencia se vean igual.


Link: https://docwiki.embarcadero.com/RADS...int_Arithmetic

No, no son flotantes si ves al inicio la definición de la tabla son enteros largos. Lo de 5, 84 debi decir 5 y 84 respectivamente para cada uno episodio y codigo. Estoy pensando hacer lo que PepCat me escribe. Pero no entiendo el porque no funciona el locate.

Neftali [Germán.Estévez] 29-11-2022 08:47:40

Cita:

Empezado por steelha (Mensaje 549429)
La sentencia es la siguiente
Código SQL [-]
SELECT * FROM EpisItems Where EpEpisodio = :epi

¿Seguro que la sentencia que hay en Dm.QryEpisodioItems en ese momento es esa?
No me cuadra. Porque si la sentencia fuera esa, el código que has puesto aquí (https://www.clubdelphi.com/foros/sho...26&postcount=1) fallaría en el Open, por la falta del parámetro :epi

Vuelvo a decirlo mismo.Si pones el profiler de SQLServer verás realmente las sentencias que se ejecutan.
El Locate es correcto y debería funcionar. Lo único que se me ocurre es que con la sentencia que estás utilizando al abrir Dm.QryEpisodioItems esos elementos ya no estén (por ejemplo porque está filtrada).

kuan-yiu 29-11-2022 14:54:59

Si en la consulta has cargado, por ejemplo:
Código Delphi [-]
Where EpEpisodio = 7
Nunca te encontrará nada con un locate por 'EpEpisodio=5 '. (El locate busca entre los resultados de la consulta, no en la BD.)
O primero cargas la consulta con EpEpisodio=5 y luego haces el locate, o bien modificas la consulta para ampliarla (quitando el where) o bien la modificas para centrarla y buscas directamente el elemento.

Yo en estos casos planto un breakpoint justo antes del locate, copio la consulta, los parámetros y los ejecuto directamente en la BD para ver exactamente lo que saca.

steelha 07-12-2022 17:35:52

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 549433)
¿Seguro que la sentencia que hay en Dm.QryEpisodioItems en ese momento es esa?
No me cuadra. Porque si la sentencia fuera esa, el código que has puesto aquí (https://www.clubdelphi.com/foros/sho...26&postcount=1) fallaría en el Open, por la falta del parámetro :epi

Vuelvo a decirlo mismo.Si pones el profiler de SQLServer verás realmente las sentencias que se ejecutan.
El Locate es correcto y debería funcionar. Lo único que se me ocurre es que con la sentencia que estás utilizando al abrir Dm.QryEpisodioItems esos elementos ya no estén (por ejemplo porque está filtrada).

Gracias neftali un error de novatos, T_T ese era el problema no le estaba pasando valor al parametro. La linea estaba en otro procedimiento que lo habia movido sin querer.. Perdon por no contestar inmediatamente, estaba enfermo con el covid otra vez.

Neftali [Germán.Estévez] 09-12-2022 09:40:40

Cita:

Empezado por steelha (Mensaje 549515)
T_T ese era el problema no le estaba pasando valor al parametro. La linea estaba en otro procedimiento que lo habia movido sin querer.. Perdon por no contestar inmediatamente, estaba enfermo con el covid otra vez.

^\||/^\||/
Pasa a veces...:D

Cita:

Empezado por steelha (Mensaje 549515)
estaba enfermo con el covid otra vez.

A mejorarse.


La franja horaria es GMT +2. Ahora son las 08:22:58.

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