|
![]() |
|
Registriert seit: 19. Okt 2003 Ort: Heilbronn 689 Beiträge Delphi 10.4 Sydney |
#1
Delphi speichert den Wert als Delphityp zwischen, da es keinen nativen Fixed Point gibt nimmt er halt einen Float.
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. ![]() |
![]() |
Registriert seit: 28. Apr 2008 Ort: Stolberg (Rhl) 6.659 Beiträge FreePascal / Lazarus |
#2
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. ![]() 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 |
![]() |
Registriert seit: 19. Okt 2003 Ort: Heilbronn 689 Beiträge Delphi 10.4 Sydney |
#3
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. ![]() 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 ![]() Nach dem Ausführen der SP in einem Datenbank-Explorer : ![]() Derselbige zeigt auch jeweils diese Werte an. Und ja, ich denke auch, dass das Ergebnis immer dasselbe sein sollte. Ist es aber nicht. ![]() |
![]() |
Registriert seit: 19. Okt 2003 Ort: Heilbronn 689 Beiträge Delphi 10.4 Sydney |
#4
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. |
![]() |
Registriert seit: 8. Jun 2002 Ort: Berglen 2.395 Beiträge Delphi 10.4 Sydney |
#5
Ich probier mal, ein Beispiel in einer extra DB zusammenzubauen und es an die Entwickler zu senden.
![]() |
![]() |
Registriert seit: 19. Okt 2003 Ort: Heilbronn 689 Beiträge Delphi 10.4 Sydney |
#6
tabelle Detail des Wareneingangs (Das Feld der Menge, wo der Fehler auftritt, ist Qty) :
Code:
Die Tabelle der Inventar-Bewegungen (Feld der Menge ist wieder Qty) :
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 );
Code:
und die SP, die die Werte kopiert :
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 );
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 ; ^ |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |