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.

Code
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;


Last edited by vippolito; 02/14/14 04:26 PM.