erro no recordcount

Delphi

09/05/2005

ola galera

estopu fazendo um aplicação no delphi7 usando bd interbase, e acesso obd usando dbexpress.

fiz uma consulta no sqlquery1 e depois eu quero saber o numero de registros obtidos usando:
nreg:= DataModule1.sqlestoque.RecordCount;
só que esse codigo dá um erro:
´dbxpress error: operation not supported´

e acontece esse erro só quando chega nessa parte do codigo que mostrei(nreg:= DataModule1.sqlestoque.RecordCount;)

eu tenho que fazer algo diferente pra dar certo?

valeu


Radolpho

Radolpho

Curtidas 0

Respostas

Gandalf.nho

Gandalf.nho

09/05/2005

Pelo que sei o DBExpress não suporta RecordCount. Vc terá que usar o método do SELECT COUNT(*) FROM tabela para obter a quantidade de registros.


GOSTEI 0
Vinicius2k

Vinicius2k

09/05/2005

Colega,

Existem casos em que o RecordCount não pode ser lido quando se utilizando dbExpress...
[quote:5273678c7e=´Help do Delphi´]Reading RecordCount will generate an exception if the dataset can’t determine the number of records. Do not read RecordCount if:

The dataset represents stored procedure.
[b:5273678c7e]The dataset represents a query that contains parameters.[/b:5273678c7e]
The dataset represents a multi-table join.[/quote:5273678c7e]

Sua situação se enquadra em alguma destas 3? Se sim, vc precisará criar outra forma para leitura, como uma outra query com um SELECT COUNT, por exemplo.

T+


GOSTEI 0
Luciano.sul

Luciano.sul

09/05/2005

é realmente o DBExpress não suporta, mas se vc estiver usando ClientDataSet para visualizar a sua consulta, este sim suporta.


GOSTEI 0
Vinicius2k

Vinicius2k

09/05/2005

Colegas,

Não é regra. O RecordCount é suportado desde que não se enquadre nas situações descritas acima.

Ex:
with SQLDataSet1 do
begin
  Close;
  CommandText := ´select * from <TABELA>´;
  Open;
  ShowMessage(IntToStr(RecordCount)); // Não gera exceção.
end;

with SQLDataSet1 do
begin
  Close;
  CommandText := ´select * from <TABELA> where <CAMPO> = :parametro´;
  ParamByName(´parametro´).AsInteger := 1;
  Open;
  ShowMessage(IntToStr(RecordCount)); // Aqui gera exceção, pois a query tem parametros
end;


Se a instrução for montada de forma que não exista parametro ou JOIN, o RecordCount pode ser lido.

T+


GOSTEI 0
Bruno Belchior

Bruno Belchior

09/05/2005

O RecordCount é suportado desde que não se enquadre nas situações descritas acima.
quer dizer que se utilizar o seguinte código é válido... :?:
var
  vSQLDataSet: TSQLDataSet;
begin
  vSQLDataSet := TSQLDataSet.Create(nil);
  ....
  vSQLDataSet.CommandText := ´Select IdAluno, Nome from Alunos where IdAluno = 1´ ;
  ....
  vSQLDataSet.RecordCount...



GOSTEI 0
Vinicius2k

Vinicius2k

09/05/2005

quer dizer que se utilizar o seguinte código é válido... :?:
var
  vSQLDataSet: TSQLDataSet;
begin
  vSQLDataSet := TSQLDataSet.Create(nil);
  ....
  vSQLDataSet.CommandText := ´Select IdAluno, Nome from Alunos where IdAluno = 1´ ;
  ....
  vSQLDataSet.RecordCount...

Exato. :wink:

T+


GOSTEI 0
Bruno Belchior

Bruno Belchior

09/05/2005

Vinicius é verdade que o DbExpress trabalha retornando apenas um registro... pq até ai o que sei é isso... (até por não suportar DBGrrid, mas acredito que isso é pelo fato de ser unidirecional)...


GOSTEI 0
Vinicius2k

Vinicius2k

09/05/2005

Bruno,

Sim. O dbExpress não tem buffer local e a cada ´Next´ solicitado ao DataSet é realizado o fetch de um único registro para o lado do cliente. Esta é a razão que faz com que o dbExpress seja considerado mais rápido que outras camadas, mas não pode ser considerada 100¬ verdadeira esta consideração porque você, dificilmente, trabalha o tempo todo sem buffer local.

Sim. O fato de não suportar TDBGrid é devido ao fato de ele ser unidirecional.
Resumindo, ele não aceita navegação, porque não tem buffer e não tem buffer porque é unidirecional.

Apenas para esclarecer, já que esta é a questão do tópico. Pode ficar ´no ar´ a dúvida: ´Se ele não tem buffer local, como pode ser lido o RecordCount?´
Para responder à isto, basta observar a implementação do método TCustomSQLDataSet.GetRecordCount, responsável pelo preenchimento da propriedade RecordCount. O ´truque´ é, por incrível que pareça, um SELECT COUNT(*)... :)

function TCustomSQLDataSet.GetRecordCount: Integer;
const
  SDistinct = ´ distinct ´;                 { do not localize }
  SSelectCount = ´select count(*) from ´;   { do not localize }
var
  TableName, Query: string;
  HoldPos: Integer;
  Status : SQLResult;
  buf : array [0..255] of char;
  Len : smallint;
begin
  if FRecords <> -1 then
    Result := FRecords
  else
  begin
    CheckConnection(eConnect);
    if Self.CommandText = ´´ then
      DatabaseError(SNoSQLStatement);
    case CommandType of
      ctStoredProc:
        DatabaseError(SNotSupported);
      ctTable:
        begin
          //Query := ´select count(*) from ´ + GetQuoteChar + FCommandText + GetQuoteChar;
          Status := GetInternalConnection.FISQLConnection.setOption(eConnQualifiedName, LongInt(CommandText));
          if Status <> 0 then
            SQLError(Status, exceptConnection);
          Status := GetInternalConnection.FISQLConnection.getOption(eConnQuotedObjectName, @buf, SizeOf(buf), Len);
          if Status <> 0 then
            SQLError(Status, exceptConnection);
          Query := ´select count(*) from ´ + buf;
        end;
      ctQuery:
        begin
          TableName := GetTableNameFromSQL(FCommandText);
          if (TableName = ´´) or (Params.Count > 0) then
            DatabaseError(SNotSupported);
          if Pos(SDistinct, LowerCase(FCommandText)) = 0 then
            Query := SSelectCount
          else
            DatabaseError(SNotSupported);
          HoldPos := Pos(SWhere, LowerCase(FCommandText));
          if HoldPos = 0 then
            Query := Query + GetQuoteChar + TableName + GetQuoteChar
          else begin
            Query := Query + GetQuoteChar + TableName + GetQuoteChar + copy(FCommandText, HoldPos, Length(FCommandText) - (HoldPos-1));
            HoldPos := Pos(sOrderBy, LowerCase(Query));
            if HoldPos > 0 then
              Query := copy(Query, 1, HoldPos - 1);
          end;
        end;
    end;
    FRecords := GetRows(Query, FSQLConnection);
    Result := FRecords;
  end;
end;


T+


GOSTEI 0
POSTAR