Reputation: 349
I can't locate any record in TADOQuery
using PK. First, I was trying to use standard Locate
method:
PPUQuery.Locate('ID', SpPlansQuery['PPONREC'], []);
It always returns False
, but manual search (passing the whole query matching ID
with given PPONREC
which is really slow) finds the desired row. I tried using loPartialKey
and switched CursorLocation of query to clUseServer
, but it didn't help.
Next, I tried to filter my PPUQuery
:
PPUQuery.Filter := 'ID = ' + VarToStr(SpPlansQuery['PPONREC']);
PPUQuery.Filtered := True;
PPUQuery.First;
But after that the PPUQuery.Eof
is True
and PPUQuery.RecordCount
equals 0
.
PPUQuery fields list:
object PPUQueryNUM: TFMTBCDField
DisplayLabel = #1053#1086#1084#1077#1088
FieldName = 'NUM'
ReadOnly = True
Precision = 38
Size = 0
end
object PPUQueryINUM: TFMTBCDField
DisplayLabel = #1053#1086#1084#1077#1088' '#1062#1052#1050
FieldName = 'INUM'
ReadOnly = True
Precision = 38
Size = 0
end
object PPUQueryONUM: TFMTBCDField
DisplayLabel = #1055#1086#1088#1103#1076#1082#1086#1074#1099#1081' '#1085#1086#1084#1077#1088
FieldName = 'ONUM'
ReadOnly = True
Precision = 38
Size = 0
end
object PPUQueryDRAWING: TStringField
DisplayLabel = #1053#1086#1084#1077#1088' '#1095#1077#1088#1090#1077#1078#1072
FieldName = 'DRAWING'
ReadOnly = True
Size = 50
end
object PPUQueryWEIGHT: TFloatField
DisplayLabel = #1042#1077#1089
FieldName = 'WEIGHT'
ReadOnly = True
end
object PPUQueryTITLE: TStringField
DisplayLabel = #1047#1072#1075#1086#1083#1086#1074#1086#1082
FieldName = 'TITLE'
ReadOnly = True
Size = 200
end
object PPUQueryPRODUCER: TFMTBCDField
DisplayLabel = #1055#1088#1086#1080#1079#1074#1086#1076#1080#1090#1077#1083#1100
FieldName = 'PRODUCER'
ReadOnly = True
Precision = 38
Size = 0
end
object PPUQueryGRAPH: TStringField
DisplayLabel = #1043#1088#1072#1092#1080#1082
FieldName = 'GRAPH'
ReadOnly = True
Size = 200
end
object PPUQueryNOTE: TStringField
DisplayLabel = #1055#1088#1080#1084#1077#1095#1072#1085#1080#1077
FieldName = 'NOTE'
ReadOnly = True
Size = 1024
end
object PPUQueryUPDATED: TDateTimeField
DisplayLabel = #1054#1073#1085#1086#1074#1083#1105#1085
FieldName = 'UPDATED'
ReadOnly = True
end
object PPUQueryRELDATE: TDateTimeField
DisplayLabel = #1044#1072#1090#1072' '#1086#1082#1086#1085#1095#1072#1085#1080#1103' '#1080#1079#1075#1086#1090#1086#1074#1083#1077#1085#1080#1103
FieldName = 'RELDATE'
ReadOnly = True
end
object PPUQueryID: TFMTBCDField
FieldName = 'ID'
ReadOnly = True
Visible = False
Precision = 38
Size = 0
end
object PPUQueryNUM_OF: TFMTBCDField
FieldName = 'NUM_OF'
ReadOnly = True
Visible = False
Precision = 38
Size = 0
end
object PPUQueryORDER_ID: TFMTBCDField
FieldName = 'ORDER_ID'
Precision = 38
Size = 0
end
object PPUQueryPLAN_ID: TFMTBCDField
FieldName = 'PLAN_ID'
Precision = 38
Size = 0
end
object PPUQueryCNUM: TStringField
FieldName = 'CNUM'
Size = 50
end
object PPUQueryCADEP: TFMTBCDField
FieldName = 'CADEP'
Precision = 38
Size = 0
end
object PPUQueryMATERIAL: TFMTBCDField
FieldName = 'MATERIAL'
Precision = 38
Size = 0
end
object PPUQueryARTICLE: TFMTBCDField
DisplayLabel = #1057#1090#1072#1090#1100#1103
FieldName = 'ARTICLE'
Precision = 38
Size = 0
end
object PPUQueryDEPTH: TFloatField
FieldName = 'DEPTH'
end
object PPUQueryPAINT: TFMTBCDField
FieldName = 'PAINT'
Precision = 38
Size = 0
end
object PPUQueryBSS: TFMTBCDField
FieldName = 'BSS'
Precision = 38
Size = 0
end
object PPUQueryQNUM: TFMTBCDField
DisplayLabel = #1054#1095#1077#1088#1077#1076#1100
FieldName = 'QNUM'
Precision = 38
Size = 0
end
object PPUQuerySERVICE: TFMTBCDField
FieldName = 'SERVICE'
Precision = 38
Size = 0
end
object PPUQueryCONTINUE: TFMTBCDField
FieldName = 'CONTINUE'
Precision = 38
Size = 0
end
object PPUQueryADVANCED: TFMTBCDField
FieldName = 'ADVANCED'
Precision = 38
Size = 0
end
object PPUQueryMETIZ: TFMTBCDField
FieldName = 'METIZ'
Precision = 38
Size = 0
end
object PPUQueryID_1: TFMTBCDField
FieldName = 'ID_1'
Precision = 38
Size = 0
end
object PPUQueryTITLE_1: TStringField
DisplayLabel = #1057#1090#1072#1090#1100#1103
FieldName = 'TITLE_1'
end
object PPUQueryORD: TFMTBCDField
FieldName = 'ORD'
Precision = 38
Size = 0
end
object PPUQueryID_2: TFMTBCDField
FieldName = 'ID_2'
Precision = 38
Size = 0
end
object PPUQueryTITLE_2: TStringField
DisplayLabel = #1052#1072#1090#1077#1088#1080#1072#1083
FieldName = 'TITLE_2'
Size = 100
end
object PPUQueryID_3: TFMTBCDField
FieldName = 'ID_3'
Precision = 38
Size = 0
end
object PPUQueryCA: TFMTBCDField
FieldName = 'CA'
Precision = 38
Size = 0
end
object PPUQueryTITLE_3: TStringField
DisplayLabel = #1047#1072#1082#1072#1079#1095#1080#1082
FieldName = 'TITLE_3'
Size = 100
end
object PPUQueryID_4: TFMTBCDField
FieldName = 'ID_4'
Precision = 38
Size = 0
end
object PPUQueryCA_1: TFMTBCDField
FieldName = 'CA_1'
Precision = 38
Size = 0
end
object PPUQueryTITLE_4: TStringField
DisplayLabel = #1055#1088#1086#1080#1079#1074#1086#1076#1080#1090#1077#1083#1100
FieldName = 'TITLE_4'
Size = 100
end
object PPUQueryID_5: TFMTBCDField
FieldName = 'ID_5'
Precision = 38
Size = 0
end
object PPUQueryARTICLE_1: TFMTBCDField
FieldName = 'ARTICLE_1'
Precision = 38
Size = 0
end
object PPUQueryMATERIAL_1: TFMTBCDField
FieldName = 'MATERIAL_1'
Precision = 38
Size = 0
end
object PPUQueryPRODUCER_1: TFMTBCDField
FieldName = 'PRODUCER_1'
Precision = 38
Size = 0
end
object PPUQueryWEIGHT_1: TFloatField
FieldName = 'WEIGHT_1'
end
object PPUQueryINUM_1: TFMTBCDField
FieldName = 'INUM_1'
Precision = 38
Size = 0
end
object PPUQueryQNUM_1: TFMTBCDField
FieldName = 'QNUM_1'
Precision = 38
Size = 0
end
Underlying database is Oracle 9 and the ID
is of type INTEGER
and is PK of table TPORDER_CMK
. PPUQuery.SQL
is:
SELECT tp.*, la.*, lm.*, ld.*, ld1.*, to_cmk.*
FROM ppu_plan.tporder_cmk tp
JOIN PPU_PLAN.LARTICLES la
ON TP.ARTICLE = LA.ID
JOIN PPU_PLAN.LMATERIAL lm
ON TP.MATERIAL = lm.id
JOIN PPU_PLAN.LCADEP ld
ON TP.CADEP = LD.ID
JOIN PPU_PLAN.LCADEP ld1
ON TP.PRODUCER = LD1.ID
JOIN PPU_PLAN.TORDER_CMK to_cmk
ON TP.order_id=TO_cmk.ID
WHERE TP.PLAN_ID = :pplan_id
DDL script for TPORDER_CMK
:
CREATE TABLE PPU_PLAN.TPORDER_CMK
(
ID INTEGER NOT NULL,
ORDER_ID INTEGER NOT NULL,
PLAN_ID INTEGER NOT NULL,
NUM INTEGER,
ONUM INTEGER,
CNUM VARCHAR2(50 BYTE),
DRAWING VARCHAR2(50 BYTE),
TITLE VARCHAR2(200 BYTE),
NUM_OF INTEGER DEFAULT 0,
CADEP INTEGER,
WEIGHT FLOAT(126),
MATERIAL INTEGER,
ARTICLE INTEGER,
DEPTH FLOAT(126),
PRODUCER INTEGER NOT NULL,
INUM INTEGER,
PAINT INTEGER NOT NULL,
BSS INTEGER NOT NULL,
QNUM INTEGER DEFAULT NULL,
SERVICE INTEGER NOT NULL,
CONTINUE INTEGER NOT NULL,
GRAPH VARCHAR2(200 BYTE),
ADVANCED INTEGER NOT NULL,
NOTE VARCHAR2(1024 BYTE),
UPDATED DATE DEFAULT SYSDATE NOT NULL,
RELDATE DATE,
METIZ INTEGER DEFAULT 0 NOT NULL
)
TABLESPACE WEB
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 80K
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
NOLOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
NOMONITORING;
CREATE INDEX PPU_PLAN.TPORDER_CMK_IDX ON PPU_PLAN.TPORDER_CMK
(ORDER_ID, PLAN_ID, NUM, ONUM, CADEP,
MATERIAL, ARTICLE, PRODUCER, PAINT, BSS,
SERVICE, CONTINUE, GRAPH, ADVANCED, UPDATED,
RELDATE, METIZ)
LOGGING
TABLESPACE WEB
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
NOPARALLEL;
CREATE UNIQUE INDEX PPU_PLAN.TPORDER_CMK_PK ON PPU_PLAN.TPORDER_CMK
(ID)
NOLOGGING
TABLESPACE WEB
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 80K
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
NOPARALLEL;
CREATE OR REPLACE TRIGGER PPU_PLAN.TRPORDER_CMK
BEFORE INSERT ON PPU_PLAN.TPORDER_CMK FOR EACH ROW
WHEN (
NEW.ID IS NULL
)
DECLARE NID INTEGER;
BEGIN
IF (:new.ID = NULL) THEN
BEGIN
SELECT SPORDER_CMK.NEXTVAL INTO NID FROM DUAL;
:new.ID := NID;
END;
END IF;
END;
/
ALTER TABLE PPU_PLAN.TPORDER_CMK ADD (
CONSTRAINT TPORDER_CMK_PK
PRIMARY KEY
(ID)
USING INDEX PPU_PLAN.TPORDER_CMK_PK
ENABLE VALIDATE);
SpPlansQuery['PPONREC']
is a TFmtBcdField
, but even specifying value literally (e.g. 18323
) doesn't help.
My previous question (Cannot assign data to client dataset) contains information that may help in finding out what am I trying to achieve.
What should I try next and how to solve this problem?
Upvotes: 1
Views: 3037
Reputation: 349
I have found temporary solution that I hate since it is memory consuming and 3 times slower than I want. Also, I apologise for answering my own questions too much, but it's the best solution I found.
I have to pass PPUQuery
and build TDictionary<Integer, Variant>
with values that I want. Next, I'm querying the dictionary instead of using TADOQuery.Locate
:
uses Generics.Collections;
procedure ReFillDataSet;
const
// IMPORTANT: check that fields count in next 2 lines would be the same
FieldsStr1 = 'FIELD_1_PPU;FIELD_2_PPU;FIELD_3_PPU';
FieldsStr2 = 'FLD_1;FLD_2;FLD_3';
var
Deleted, Changed: Boolean;
FieldValues1, FieldValues2: Variant;
Idx1, Idx2: TDictionary<Integer, Variant>
begin
ComparisonDataSet.DisableControls;
ComparisonDataSet.EmptyDataSet;
// building indexes
Idx1 := TDictionary<Integer, Variant>.Create;
Idx1.Clear;
PPUQuery.First;
while not PPUQuery.Eof do begin
Idx1.Add(PPUQuery['ID'], PPUQuery[FieldsStr2]);
PPUQuery.Next;
end;
Idx2 := TDictionary<Integer, Variant>.Create;
Idx2.Clear;
SpPlansQuery.First;
while not SpPlansQuery.Eof do begin
Idx2.Add(SpPlansQuery['PPONREC'], Null);
SpPlansQuery.Next;
end;
// deleted and changed records
SpPlansQuery.First;
while not SpPlansQuery.Eof do
begin
FieldValues1 := SpPlansQuery[ReplaceStr(FieldsStr1, '_PPU', '')];
//Deleted := not PPUQuery.Locate('ID', SpPlansQuery['PPONREC'], []);
Deleted := not Idx1.ContainsKey(SpPlansQuery['PPONREC']);
if not Deleted then
begin
FieldValues2 := Idx1[SpPlansQuery['PPONREC']];
Changed := False;
// count fields
Fields := TList.Create;
try
ComparisonDataSet.GetFieldList(Fields, FieldsStr1);
for J := 0 to Fields.Count - 1 do
begin
if Changed then
System.Break;
Changed := Changed or (FieldValues1[J] <> FieldValues2[J]);
end;
finally
Fields.Free;
end;
end;
if Deleted or Changed then
begin
ComparisonDataSet.Append;
ComparisonDataSet[ReplaceStr(FieldsStr1, '_PPU', '')] := FieldValues1;
if Deleted then
ComparisonDataSet['Oper'] := 2
else begin
ComparisonDataSet['Oper'] := 1;
ComparisonDataSet[FieldsStr1] := FieldValues2;
end;
ComparisonDataSet.Post;
end;
SpPlansQuery.Next;
end;
// added records
PPUQuery.First;
while not PPUQuery.Eof do begin
if not {SpPlansQuery.Locate('PPONREC', PPUQuery['ID'], [])} Idx2.ContainsKey(PPUQuery['ID']) then begin
ComparisonDataSet.Append;
ComparisonDataSet[FieldsStr1] := PPUQuery[FieldsStr2];
ComparisonDataSet['Oper'] := 0;
ComparisonDataSet.Post;
end;
PPUQuery.Next;
end;
Idx1.Free;
Idx2.Free;
ComparisonDataSet.First;
ComparisonDataSet.EnableControls;
end;
Upvotes: 1