I am posting this to help anyone else who might be using QuantumGrid with Direct Oracle Access.
As stated in the TcxDbDataModeController.OnDetailFirst, normally the controller handles the parameterized elements of the SQL query, but for some DataSets you will need to use this
event. This is the case with TOracleDataSet. The proper steps are as follows;
1) Set the parameters of the
TcxGrid.DataControler.DetailKeyFieldNames, TcxGrid.DataControler.KeyFieldNames and TcxGrid.DataControler.MasterKeyFieldNames
2) Do NOT Set the values of TOracleDataSet.Master,
TOracleDataSet.MasterFields and TOracleDataSet.DetailFields.
3) Write a routine that will place the parameter
values into the parameter variables.
I have written a generic routine that can be used as a
basis for this routine. It can be used for single or multiple parameterized queries. It uses one custom function "GetNextFieldInString" which I use for parsing CSV import files. This function strips the string before the ';', returning the sting that was stripped. It also removes the retuned characters plus the ';' from the string passed. I did this to make the routine more compact and easier to read.
procedure TFrmEditOrders.GtvPickupsDataControllerDataModeControllerDetailFirst(Sender: TcxDBDataModeController; ADataSet: TDataSet; const AMasterDetailKeyFieldNames: string;
const AMasterDetailKeyValues: Variant; var AReopened: Boolean);
Var
KeyFieldNames : String;
I: Integer;
St : String;
RefreshDetail : Boolean;
VarArrDimCount : Integer;
begin
if (ADataSet is TOracleDataSet) then
begin
With (ADataSet as TOracleDataSet) do
begin
VarArrDimCount:=VarArrayDimCount(AMasterDetailKeyValues);
if VarArrDimCount=0 then
begin
if GetVariable(AMasterDetailKeyFieldNames)<>AMasterDetailKeyValues then
begin
if Active then
CloseAll;
SetVariable(AMasterDetailKeyFieldNames,AMasterDetailKeyValues);
Open;
AReopened:=True;
end;
end
else
begin
RefreshDetail:=False;
KeyFieldNames:=AMasterDetailKeyFieldNames;
I:=0;
while Not RefreshDetail and (VarArrayHighBound(AMasterDetailKeyValues,1)>=I) do
begin
// Function GetNextFieldInString(Var St : String; EofStr,EolStr : String) : String;
// This function returns the string before the ';' and also removes the returned string plus the ';' from the string that was passed (St)
St:=GetNextFieldInString(KeyFieldNames,';',CrLf);
if GetVariable(St)<>AMasterDetailKeyValues[I] then
RefreshDetail:=True;
Inc(I);
end;
if RefreshDetail then
begin
if Active then
CloseAll;
KeyFieldNames:=AMasterDetailKeyFieldNames;
for I := VarArrayLowBound(AMasterDetailKeyValues,1) to VarArrayHighBound(AMasterDetailKeyValues,1) do
begin
St:=GetNextFieldInString(KeyFieldNames,';',CrLf);
SetVariable(St,AMasterDetailKeyValues[I]);
end;
Open;
AReopened:=True;
end;
end;
end;
end;
end;