AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

[Firebird]

Ein Thema von MyRealName · begonnen am 18. Mai 2014 · letzter Beitrag vom 19. Mai 2014
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
675 Beiträge
 
Delphi 10.4 Sydney
 
#11

AW: [Firebird]

  Alt 19. Mai 2014, 14:35
Delphi speichert den Wert als Delphityp zwischen, da es keinen nativen Fixed Point gibt nimmt er halt einen Float.
Nur dass Delphi den ja korrekt schreibt.

Ich erklär mal die Idee kurz :

Ich mache einen Wareneingang, es kommen 422.24 Einheiten vonn irgendwas rein (zum Bsp. Apotheken arbeiten oft mit solchen Mengen). Das Document des Wareneingangs schreibt das ganze in seine Tabellen (Master-Detail). Dort kommt alles korrekt an. Das ganze wird mit einem TUniQuery als "INSERT INTO ..." gemacht.
Wenn das alles fertig ist wird in einer anderen Transaction eine Stored Procedure aufgerufen, die dann diverse Sachen macht, unter anderem die Warenbewegung registrieren, so dass diese 422.24 Einheiten im Inventar auftreten. Dazu haben wir eine Container-Tabelle, in welche wir reinschreiben, wann welches Produkt mit Welche Dokument bewegt wurde (Wareneingang, Rechnung, Rückgabe, Rücknahme, Produktion, Bewegung zw. Lagern etc).
In diesem Container kommt der Wert (wenn die SP unter Delphi aufgerufen wird) als 422.23999 an (die SP nutzt nur die Nummer des Dokuments als Parameter, der Wert der Einheiten wird drin erst festgestellt), obwohl die Quell - Tabelle 422.24000 als Wert hat.
Rufe ich diese SP allerdings im SQL Tool auf, geht es korrekt.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#12

AW: [Firebird]

  Alt 19. Mai 2014, 14:47
In diesem Container kommt der Wert (wenn die SP unter Delphi aufgerufen wird) als 422.23999 an (die SP nutzt nur die Nummer des Dokuments als Parameter, der Wert der Einheiten wird drin erst festgestellt), obwohl die Quell - Tabelle 422.24000 als Wert hat.
Rufe ich diese SP allerdings im SQL Tool auf, geht es korrekt.
Woher weißt Du denn daß einmal 422.23999 und einmal 422.24000 genutzt werden?
Solltest Du dafür zwei unterschiedliche Programme/Tools nutzen, ist das der berühmte Vergleich Äpfel/Birnen.

Wenn die SP (StoredProcedure einer Datenbank) als Parameter die ID eines Datensatzes übergeben bekommt und keine Weiteren Parameter unter der Hand (Nebeneffekt) geholt werden, dann sollte das Ergebnis bei der selben ID immer das selbe sein.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
675 Beiträge
 
Delphi 10.4 Sydney
 
#13

AW: [Firebird]

  Alt 19. Mai 2014, 14:54
tabelle Detail des Wareneingangs (Das Feld der Menge, wo der Fehler auftritt, ist Qty) :

Code:
CREATE TABLE IPDET (
    TIPO              CHAR(2) NOT NULL,
    NUMBER            INTEGER NOT NULL,
    CONTEO            INTEGER NOT NULL,
    ITEM              CHAR(15) NOT NULL,
    LOCATION          CHAR(3) NOT NULL,
    COST              NUMERIC(15,2),
    QTY               NUMERIC(15,5),
    QTYREC            NUMERIC(15,2),
    QTYPEND           NUMERIC(15,2),
    EXTEND            NUMERIC(15,2),
    PESO              NUMERIC(15,2),
    COSTCDESC         NUMERIC(15,2),
    COSTCFLETE        NUMERIC(15,2),
    REFOC             CHAR(7),
    REFREC            CHAR(7),
    CLOSEDOC          CHAR(5),
    QTYDEV            NUMERIC(15,2),
    CC                NUMERIC(15,2),
    PB                NUMERIC(15,2),
    QTYB              NUMERIC(15,2),
    QTYBDEV           NUMERIC(15,2),
    PORCDCT           NUMERIC(15,2),
    VALORDCT          NUMERIC(15,2),
    E                 SMALLINT default 1 NOT NULL,
    DESTINO           SMALLINT default 1,
    S                 SMALLINT default 1 NOT NULL,
    LOTE              CHAR(20) default 1,
    COSTMC            NUMERIC(15,2) default 0,
    NODOCR            INTEGER,
    TPDOCR            CHAR(5),
    EDOCR             INTEGER,
    SDOCR             INTEGER,
    FECHA_VENCIMIENTO DATE,
    COLOR             CHAR(25),
    COD_TALLA         CHAR(5),
    ICO               NUMERIC(15,2) DEFAULT "0",
    VLREXT            NUMERIC(15,2) DEFAULT "0",
    VALOR_IVA         NUMERIC(15,2),
    COD_IVA           SMALLINT,
    COD_LISTA         INTEGER,
    DSC_ADICIONAL     VARCHAR(100),
    NUR_SERIAL        INTEGER,
    COSTU_SF          NUMERIC(15,2) DEFAULT 0,
    COSTU_CF          NUMERIC(15,2) DEFAULT 0,
    COST_KILO         NUMERIC(15,2) DEFAULT 0,
    ITEMID            INTEGER,
    DOCID             INTEGER,
    CONTEO_IA         INTEGER,
    CONTEO_RESP       INTEGER
);
Die Tabelle der Inventar-Bewegungen (Feld der Menge ist wieder Qty) :

Code:
CREATE TABLE ITEMACT (
    CONTEO         INTEGER NOT NULL,
    LOCATION       CHAR(3) NOT NULL,
    ITEM           CHAR(15) NOT NULL,
    ID_N           BIGINT,
    TIPO           CHAR(2),
    BATCH          INTEGER,
    FECHA          DATE,
    QTY            NUMERIC(15,5),
    VALUNIT        NUMERIC(15,2),
    VALCDCT        NUMERIC(15,2),
    VALCFLE        NUMERIC(15,2),
    QTYB           NUMERIC(15,2),
    E              SMALLINT,
    S              SMALLINT,
    LOTE           CHAR(20),
    TOTPARCIAL     NUMERIC(15,2),
    PRIORIDAD      INTEGER,
    COLOR          CHAR(25),
    COD_TALLA      CHAR(5),
    PRECIO         NUMERIC(15,2),
    COSTP_KARDEX   NUMERIC(15,2) DEFAULT 0,
    SALDO_KARDEX   NUMERIC(15,2) DEFAULT 0,
    SALDODU_KARDEX NUMERIC(15,2) DEFAULT 0,
    PARCIAL_KARDEX NUMERIC(15,2) DEFAULT 0,
    TOTAL_KARDEX   NUMERIC(15,2) DEFAULT 0,
    COD_LISTA      INTEGER DEFAULT -1,
    COSTO_PROMEDIO TNUMERICO DEFAULT 0 /* TNUMERICO = NUMERIC(15,2) DEFAULT 0 */,
    ER             INTEGER,
    SR             INTEGER,
    TIPOR          CHAR(2),
    NUMEROR        INTEGER,
    HORA           DATE,
    FCH_VNCMNTO    DATE,
    ID_CURVA       INTEGER,
    ID_LOTE        INTEGER
);
und die SP, die die Werte kopiert :

Code:
create or alter procedure IP_ENTRADA_DEVOLUCION_GRABAR (
    E integer,
    S integer,
    TIPO char(2),
    NUMERO integer)
as
declare variable EDOCR integer;
declare variable SDOCR integer;
declare variable TPDOCR char(2);
declare variable NODOCR integer;
declare variable TOTALITEMS numeric(15,2);
declare variable LOCATION char(3);
declare variable QTY numeric(15,5);
declare variable ITEM varchar(15);
declare variable CONTADOR integer;
declare variable SALDO numeric(15,2);
declare variable DOCTIPDOC char(2);
declare variable DOCUMENTO char(2);
declare variable COSTO numeric(15,2);
declare variable TOTPARCIAL numeric(15,2);
declare variable ENTMC varchar(5);
declare variable ID_N bigint;
declare variable FECHA date;
declare variable CONTEO integer;
declare variable COST numeric(15,2);
declare variable QTYB numeric(15,2);
declare variable LOTE char(20);
declare variable PORCDCT numeric(15,2);
declare variable FECHA_VENCIMIENTO date;
declare variable COLOR char(25);
declare variable COD_TALLA char(5);
declare variable ICO numeric(15,2);
declare variable CONTEO1 integer;
declare variable FCH_VNCMNTO date;
declare variable ID_LOTE integer;
declare variable CONTEO_IA integer;
declare variable CONT integer;
BEGIN
  SELECT IP.ENTMC,IP.ID_N,IP.FECHA,T.TIPO FROM IP, TIPDOC T
  WHERE IP.TIPO=:TIPO AND IP.NUMBER=:NUMERO AND IP.E=:E AND IP.S=:S
        AND IP.E=T.E AND IP.S=T.S AND IP.TIPO=T.CLASE
  INTO :ENTMC, :ID_N, :FECHA, :DOCUMENTO;

  if ((:ENTMC = '') OR (:ENTMC IS Null)) then
    ENTMC = 'False';

 /*****************************************************************************/
 /***                Actualizar transacciones del detalle                  ***/
 /*****************************************************************************/

  -- first we delete the register in ItemACT from what was deleted in ipdet
  DELETE FROM ItemACT IA WHERE IA.E=:E AND IA.S=:S AND IA.Tipo=:Tipo and IA.Batch=:Numero
                         AND NOT EXISTS (SELECT * FROM ipdet ipd WHERE ipd.conteo_ia=ia.conteo);

  FOR SELECT D.CONTEO,D.ITEM,D.LOCATION,D.COST,D.QTY,
             D.QTYB, D.LOTE,D.PORCDCT, D.NODOCR,D.TPDOCR,D.EDOCR,
             D.SDOCR,D.FECHA_VENCIMIENTO,D.color,D.cod_talla,D.ico,
             T.TIPO, fecha_vencimiento, D.Conteo_IA
      FROM IPDET D
      LEFT JOIN TIPDOC T ON (D.EDOCR=T.E AND D.SDOCR=T.S AND D.TPDOCR=T.CLASE)
      WHERE D.E=:E AND D.S=:S AND D.TIPO=:TIPO AND D.NUMBER=:NUMERO
      INTO :CONTEO, :ITEM, :LOCATION, :COST, :QTY,
           :QTYB, : LOTE,:PORCDCT, :NODOCR,:TPDOCR, :EDOCR,
           :SDOCR, :FECHA_VENCIMIENTO,:color,:cod_talla,:ico,
           :DOCTIPDOC, :FCH_VNCMNTO, :Conteo_IA
  DO BEGIN
    costo = :cost - ((cost * porcdct)/100);
    IF (:documento = 'DP') THEN BEGIN
      qty = qty *-1;
      qtyb = qtyb *-1;
    end

    IF (:Conteo_IA IS NULL) THEN
      Conteo_IA = 0;

    if (:qty = 0 ) then
      totparcial = costo;
    else
      totparcial = costo * qty;
    ID_Lote = -1;

    /*Actualizar lotes de inventario*/
    IF ((:LOTE<>'') AND NOT (:LOTE is null)) THEN BEGIN
      SELECT ID FROM LOTES_INVENTARIO
      WHERE CODIGO=:LOTE AND ITEM=:ITEM
            AND FECHAVENCIMIENTO=:FECHA_VENCIMIENTO
      INTO :ID_Lote;
      IF (:ID_Lote=-1) THEN BEGIN
        INSERT INTO LOTES_INVENTARIO(CODIGO,FECHAVENCIMIENTO,ITEM)
        VALUES(:LOTE,:FECHA_VENCIMIENTO,:ITEM) RETURNING ID INTO :ID_LOTE;
      END
    END

    IF (:entmc = 'False') THEN BEGIN
      -- now we insert the ones that are newly added or update the existing ones
      SELECT Count(Conteo) FROM ItemACT WHERE Conteo=:Conteo_IA INTO :Cont;
      IF (:Cont = 0) THEN BEGIN
        INSERT INTO ItemACT (Conteo, item, location, fecha, qty, qtyb, tipo, valunit,id_n,batch,valcdct,valcfle,e,s,totparcial,color,cod_talla,lote,fch_vncmnto, ID_Lote)
        VALUES (:Conteo_IA, :Item, :Location,:fecha,:qty,:qtyb,:TIPO,:costo,:id_n,:numero,0,0,:e,:s,:totparcial,:color,:cod_talla,:lote,:fch_vncmnto, :ID_LOTE) Returning Conteo INTO :Conteo_IA;
        UPDATE IPDet SET Conteo_IA=:Conteo_IA WHERE E=:E AND S=:S AND Tipo=:Tipo AND Number=:Numero AND Conteo=:Conteo;
      END ELSE BEGIN
        UPDATE ItemACT SET Item=:Item, Location=:Location, Fecha=:Fecha, Qty=:Qty, QtyB=:QtyB, Tipo=:Tipo, ValUnit=:Costo,
                           ID_N=:ID_N, Batch=:Numero, ValcDct=0, Valcfle=0, E=:E, S=:S, TotParcial=:Totparcial, Color=:Color,
                           Cod_Talla=:Cod_Talla, Lote=:Lote, Fch_Vncmnto=:Fch_Vncmnto, ID_Lote=:ID_Lote
        WHERE Conteo=:Conteo_IA;
        SELECT Qty FROM ItemACT WHERE Conteo=:Conteo_IA INTO :Qty;
      END
    END ELSE BEGIN
     update invmecD set cantleg=cantleg+:QTY
     where e=:EDOCR and s=:SDOCR and tipo=:TPDOCR and numero=:NODOCR
     and item=:ITEM and location=:LOCATION;

     update itemdet set consignacion=consignacion-:QTY
     where item=:ITEM and location=:LOCATION;

     SELECT COUNT(*) FROM MCEA
     WHERE EMPRESAEA=:E AND SUCURSALEA=:S AND TIPOEA=:TIPO AND NUMEROEA=:NUMERO
     AND NUMEROMC=:NODOCR AND TIPOMC=:TPDOCR AND EMPRESAMC=:EDOCR AND SUCURSALMC=:SDOCR
     INTO :CONTEO1;
     IF ((:CONTEO1=0) OR (:CONTEO1 IS NULL)) THEN
     BEGIN
       INSERT INTO MCEA(NUMEROMC,TIPOMC,EMPRESAMC,SUCURSALMC,EMPRESAEA,SUCURSALEA,NUMEROEA,TIPOEA)
       VALUES(:NODOCR,:TPDOCR,:EDOCR,:SDOCR,:E,:S,:NUMERO,:TIPO);
     END
   end

   /*actualizar cantidades en ordenes de compra*/
   IF (:DOCTIPDOC='OC') THEN
   BEGIN
      SELECT COUNT(*) FROM OC_IP
      WHERE E=:E AND S=:S AND TYPEIP=:TIPO AND NUMBERIP=:NUMERO
      INTO :CONTADOR;
      IF ((:CONTADOR IS NULL) OR (:CONTADOR=0)) THEN
      BEGIN
        INSERT INTO OC_IP(TYPEOC,NUMBEROC,TYPEIP,NUMBERIP,E,S)
        VALUES(:TPDOCR,:NODOCR,:TIPO,:NUMERO,:E,:S);
      END
   END


   /*Actualizar informacion del producto*/
   UPDATE ITEM SET COSTU=:COSTO,INDATE=:FECHA
   WHERE ITEM=:ITEM;

   UPDATE ITEM SET IMPSTOCONSUMO=:ICO
   WHERE ITEM=:ITEM AND IMPSTOCONSUMO <:ICO AND USAICO='S';

   /*Actualizar la lista de proveedores del item*/
   SELECT COUNT(*) FROM ITEM_PROVEEDOR
   WHERE ITEM=:ITEM AND ID_N=:ID_N
   INTO :CONTADOR;
   IF ((:CONTADOR IS NULL) OR (:CONTADOR=0)) THEN
   BEGIN
     INSERT INTO ITEM_PROVEEDOR(ITEM,ID_N,COSTO,FECHA)
     VALUES(:ITEM,:ID_N,:COSTO,:FECHA);
   END

   EXECUTE PROCEDURE COSTOPROMEDIO(:ITEM);

 END


 /*****************************************************************************/
 /***  Actualizar documentos de respaldo de la entrada de almacen          ***/
 /*****************************************************************************/

 /*Actualizar estado de la orden de compra*/
 FOR SELECT O.TYPEOC,O.NUMBEROC,SUM(D.QTY-D.RECIBIDO)
     FROM OC_IP O, IPOCD D
     WHERE O.E=:E AND O.S=:S AND O.TYPEIP=:TIPO AND O.NUMBERIP=:NUMERO
     AND O.E=D.E AND O.S=D.S AND O.TYPEOC=D.TIPO AND O.NUMBEROC=D.NUMBER
     GROUP BY O.TYPEOC,O.NUMBEROC
     INTO :TPDOCR,:NODOCR,:SALDO
 DO
 BEGIN
   IF (:SALDO>0) THEN
   BEGIN
    UPDATE IPOCE SET ESTADO='PARCIAL'
    WHERE E=:E AND S=:S AND TIPO=:TPDOCR AND NUMBER=:NODOCR;
   END
   ELSE IF (:SALDO=0) THEN
   BEGIN
    UPDATE IPOCE SET ESTADO='CERRADO'
    WHERE E=:E AND S=:S AND TIPO=:TPDOCR AND NUMBER=:NODOCR;
   END
 END


 /*Actualizar el costo total de la entrada o devolucion*/
 TOTALITEMS=0;
 SELECT SUM(EXTEND) FROM IPDET
 WHERE E=:E AND S=:S AND TIPO=:TIPO AND NUMBER=:NUMERO
 INTO :TOTALITEMS;
 IF (:TOTALITEMS IS NULL) THEN
  TOTALITEMS=0;

 IF (:DOCUMENTO='EA') THEN
 BEGIN
   UPDATE IP SET TOTALITEMS=:TOTALITEMS
   WHERE E=:E AND S=:S AND TIPO=:TIPO AND NUMBER=:NUMERO;
 END
 ELSE
 BEGIN
   UPDATE IP SET TOTALITEMS=:TOTALITEMS
   WHERE E=:E AND S=:S AND TIPO=:TIPO AND NUMBER=:NUMERO;
 END
END^

SET TERM ; ^
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
675 Beiträge
 
Delphi 10.4 Sydney
 
#14

AW: [Firebird]

  Alt 19. Mai 2014, 15:05
In diesem Container kommt der Wert (wenn die SP unter Delphi aufgerufen wird) als 422.23999 an (die SP nutzt nur die Nummer des Dokuments als Parameter, der Wert der Einheiten wird drin erst festgestellt), obwohl die Quell - Tabelle 422.24000 als Wert hat.
Rufe ich diese SP allerdings im SQL Tool auf, geht es korrekt.
Woher weißt Du denn daß einmal 422.23999 und einmal 422.24000 genutzt werden?
Solltest Du dafür zwei unterschiedliche Programme/Tools nutzen, ist das der berühmte Vergleich Äpfel/Birnen.

Wenn die SP (StoredProcedure einer Datenbank) als Parameter die ID eines Datensatzes übergeben bekommt und keine Weiteren Parameter unter der Hand (Nebeneffekt) geholt werden, dann sollte das Ergebnis bei der selben ID immer das selbe sein.

Gruß
K-H
mit falschem Wert nach dem Speichern des Wareneingangs :
http://puu.sh/8Styd.png

Nach dem Ausführen der SP in einem Datenbank-Explorer :
http://puu.sh/8StAY.png

Derselbige zeigt auch jeweils diese Werte an. Und ja, ich denke auch, dass das Ergebnis immer dasselbe sein sollte. Ist es aber nicht.
  Mit Zitat antworten Zitat
Benutzerbild von MyRealName
MyRealName

Registriert seit: 19. Okt 2003
Ort: Heilbronn
675 Beiträge
 
Delphi 10.4 Sydney
 
#15

AW: [Firebird]

  Alt 19. Mai 2014, 16:37
Also nach langer Suche habe ich das folgende herausgefunden :

1. Delphi hat nichts damit zu tun. Es ist ein Bug im Firebird 64bit

Der Unterschied war dass ich in der Datenbank die SP direkt aufgerufen habe, wenn ich von Delphi aus das getan habe, ging das über eine Zwischen-SP, die mir das Arbeiten mit verschiedenen Typen von Dokumenten vereinfacht zu einem Aufruf.
Rufe ich die SP direkt auf, alles ok. Rufe ich die Zwischen-SP auf, welche dann die finale SP mit den gleichen Parametern aufruft, kommt es zu diesem Fehler.
Ich konnte das auch in Delphi nachvollziehen, wenn ich den Aufruf änderte und in Delphi direkt die SP aufgerufen habe, dann funktionierte es.

Ausserdem konnte ich dann nachvollziehen, dass das nur in Firebird x64 passiert. Als ich den deinstalliert habe und dafür den 32bit draufgehauen habe, ging alles, egal wie ich die SP aufrief, direkt, indirekt oder von Delphi.

Konklusion : Bei den Kunden den firebird 64bit runter und nur nch 32bit drauf.

Danke an alle, die versucht haben, zu helfen.
Ist scheinbar kein Problem, was hier im Forum gelöst werden kann.
Ich probier mal, ein Beispiel in einer extra DB zusammenzubauen und es an die Entwickler zu senden.
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.380 Beiträge
 
Delphi 10.3 Rio
 
#16

AW: [Firebird]

  Alt 19. Mai 2014, 16:46
Ich probier mal, ein Beispiel in einer extra DB zusammenzubauen und es an die Entwickler zu senden.
Danke
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz