Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.

Public Report
Report From: Delphi-BCB/Database/DBExpress    [ Add a report in this area ]  
Report #:  103564   Status: Reported
TDBXReader must have RecordCount property or function..
Project:  Delphi Build #:  16.0.4358.45540
Version:    16.3 Submitted By:   Tugrul HELVACI
Report Type:  Suggestion / Enhancement Request Date Reported:  2/21/2012 12:33:23 AM
Severity:    Commonly encountered problem Last Updated: 2/22/2012 8:08:20 PM
Platform:    All platforms Internal Tracking #:  
Resolution: None (Resolution Comments) Resolved in Build: : None
Duplicate of:  None
Voting and Rating
Overall Rating: (1 Total Rating)
5.00 out of 5
Total Votes: 10
Description
Related to Report# 103458

TDBXReader class doesnt have a RecordCount property or function. So when you want to convert TDBXReader to TJSONObject it will be a problem. Empty reader doesnt convert.(Reader to Json and then Json to ClientDataSet is a problematic)

So how can i make a decision to convert or not if TDBXReader doesnt have a RecordCount or similar functionality ?

I know DBX is unidirectional, so we cant know RecordCount unless using while Next do.. But i think it can be do internally when adding TDBXRow in TDBXReader ;)

My solution is RETURN ROWCOUNT_BIG() function in my stored procedure and Delphi side is ;

  TDBXReaderHelper = class helper for TDBXReader
  private
    function GetRecordCount : Int64;
  public

    property RecordCount : Int64 read GetRecordCount;
  end;

  function TDBXReaderHelper.GetRecordCount: Int64;
  var
    param : TDBXParameter;
  begin
    Result := 0;

    if Self.FCommand <> nil then
    begin
      param := Self.FCommand.Parameters.ParamByName('@RETURN_VALUE');

      if param <> nil then
        Result := param.Value.AsInt64;
    end;
  end;
Steps to Reproduce:
Sample project is attached.
Workarounds
None
Attachment
QualityCentralTest.zip
Comments

Tomohiro Takahashi at 2/21/2012 6:20:30 PM -
Could you please attach sample project to confirm your issue?

Tugrul HELVACI at 2/22/2012 5:54:37 AM -
Of course i can send a sample project. i will add my test Project with zip format.

unit uDBXReaderTestForQC;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DBXMSSQL, Data.DB, Vcl.Grids,
  Vcl.DBGrids, Vcl.StdCtrls, DBClient, Data.SqlExpr, DBXCommon, DBXJSON;

type
  TForm1 = class(TForm)
    conn: TSQLConnection;
    btnGetReader: TButton;
    btnConvertReader: TButton;
    DBGrid1: TDBGrid;
    dsDummy: TDataSource;
    procedure btnGetReaderClick(Sender: TObject);
    procedure btnConvertReaderClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

  Reader : TDBXReader = nil;
  JsonReader : TJSONObject = nil;

implementation
uses
  Data.DBXDBReaders,
  Data.DBXJSONCommon, // TDBXJSONTools
  Data.DBXCommonTable; // TDBXJSONTableReader

{$R *.dfm}

function ToClientDataSet(const Value : TJSONObject) : TClientDataSet;
var
  aReader : TDBXReader;
begin
  Result := nil;

  if Value <> nil then
  begin
    aReader := TDBXJSONTableReader.Create(nil, Value, false);

    if aReader <> nil then
    begin
      Result := TDBXDataSetReader.ToClientDataSet(nil, aReader, false);
      Result.MergeChangeLog;
      Result.LogChanges := true;

      aReader.Free;
    end;
  end;
end;

procedure TForm1.btnConvertReaderClick(Sender: TObject);
var
  cds : TClientDataSet;
begin
  cds := nil;

  if JSonReader <> nil then
  begin
    cds := ToClientDataSet(JSonReader);  // "EDatabaseError : No fields defined.  Cannot create dataset." Because Reader is empty.

    if cds <> nil then
      dsDummy.DataSet := cds;
  end;
end;

(*
CREATE PROCEDURE sp_Person_Browse
AS

SELECT


'Tomohiro'
AS Name,


'Takahashi'
AS SurName,


'Tomohiro Takahashi' AS FullName

FROM Persons

WHERE 1 = 2
*)
procedure TForm1.btnGetReaderClick(Sender: TObject);
var
  cmd : TDBXCommand;
begin
  if not conn.Connected then
    conn.Open;

  cmd := conn.DBXConnection.CreateCommand;
  cmd.CommandType := TDBXCommandTypes.DbxStoredProcedure;
  cmd.Text := 'sp_Person_Browse';

  cmd.Prepare;

  Reader := cmd.ExecuteQuery;

  // At this point, I have to know if Reader is empty or not. TDBXReader has not got IsEmpty or RecordCount etc. functionality. So how can i decide
  // to convert TDBXReader to TJSONObject or not ? So, we need IsEmpty or RecordCount property or function for TDBXReader. Or TDBXJSONTools.TableToJSON function must return
  // nil or TJSONNull if it's Reader is Empty..
  // But i think TDBXReader.RecordCount property will be very helpfull for programmers(both internal VCL programmers and VCL users like me). Please implement it..
  JsonReader := TDBXJSONTools.TableToJSON(Reader, 10000000, false);
end;

end.

Server Response from: ETNACODE01