Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MS SQL Server (https://www.clubdelphi.com/foros/forumdisplay.php?f=23)
-   -   Problema con RecordCount (https://www.clubdelphi.com/foros/showthread.php?t=79207)

Jere_84 15-06-2012 15:39:28

Problema con RecordCount
 
Hola gente!, hice un procedimiento que obtiene los campos que pertenecen a un determinado indice. Para esto, utilice las tablas del sistema sys.Columns, sys.Index_Columns y sys.Indexes. Antes que nada les menciono que la sentencia SQL Select que utiliza el TSQLQuery esta probada, funciona perfectamente.
El procedimiento crea un objeto SQLQuery, le asigno el SQLConnection y en su propiedad SQL agrego las sentencias. Esta pueden devolver uno o mas campos, por lo tanto, para saber esto aplico la propiedad RecordCount, que al ejecutarse produce el error: 'El nombre de objeto sys.columns no es valido'.
Recalco que es con esta propiedad que surge el inconveniente ya que si no la aplico, puedo obtener sus datos de manera habitual.
La solución seria utilizar algún otro tipo de propiedad o configurar algo que me este faltando. La prepare carece en este componente.
Bueno escucho sugerencias.

Slds.

Casimiro Notevi 15-06-2012 16:01:41

Yo no me he enterado de lo que estás haciendo, de lo que quieres conseguir, del problema que tienes ni de nada :D

Jere_84 15-06-2012 16:09:55

Código:

Código Delphi [-]
var
  oQTempCamposIndices : TSQLQuery;
  vCampos: string;
//....
begin
  oQTempCamposIndices := TSQLQuery.Create(nil);
  oQTempCamposIndices.SQLConnection:= SQLDataset.SQLConnection;
       with oQTempCamposIndices do
        begin
          SQL.Clear;
          SQL.Add('Select Columnas.name as Campo From sys.columns as Columnas ');
          SQL.Add('INNER JOIN sys.index_columns as ColIndices on ColIndices.object_id = Columnas.object_id ');
          SQL.Add('AND ColIndices.column_id = Columnas.column_id ');
          SQL.Add('INNER JOIN sys.indexes as Indices on Indices.object_id = ColIndices.object_id ');
          SQL.Add('AND Indices.index_id = ColIndices.index_id ');
          SQL.Add('Where Indices.name = ' + QuotedStr(Indice));
          oQTempCamposIndices.Open;
          //First;
          if oQTempCamposIndices.RecordCount > 1 then <------- ERROR: El nombre de objeto sys.columns no es valido.
          begin
            First;
            while not eof do
              vCampos := vCampos + sc.Trim(oQTempCamposIndices.Fieldbyname('Campo').AsString) + ';';
              next;
          end
          else
            vCampos := vCampos + sc.Trim(oQTempCamposIndices.Fieldbyname('Campo').AsString);
        end;

microbiano 15-06-2012 16:33:49

Prueba asi
 
Código Delphi [-]
with oQTempCamposIndices do
        begin
          SQL.Clear;
          SQL.Add('Select Columnas.name as Campo From sys.columns as Columnas ');
          SQL.Add('INNER JOIN sys.index_columns as ColIndices on ColIndices.object_id = Columnas.object_id ');
          SQL.Add('AND ColIndices.column_id = Columnas.column_id ');
          SQL.Add('INNER JOIN sys.indexes as Indices on Indices.object_id = ColIndices.object_id ');
          SQL.Add('AND Indices.index_id = ColIndices.index_id ');
          SQL.Add('Where Indices.name = ' + QuotedStr(Indice));
          oQTempCamposIndices.Open;
          //First;
          if (not  eof) then
           begin
            //while not eof do
              vCampos := vCampos + sc.Trim(oQTempCamposIndices.Fieldbyname('Campo').AsString) + ';';
              next;     
           end
         else
          begin
            vCampos := vCampos + sc.Trim(oQTempCamposIndices.Fieldbyname('Campo').AsString);     
           end;   
        end;

mas o menos

microbiano 15-06-2012 18:24:25

bueno y te sirvio?

Jere_84 15-06-2012 20:59:29

Cita:

Empezado por microbiano (Mensaje 435202)
bueno y te sirvio?

No recorre el while solo pasa una vez y a la siguiente se va a finally no se porque, siendo que hay otros campos mas. Ademas desmarque el First para que se posiciones sobre el primer lugar, pero nada..

microbiano 15-06-2012 21:07:29

haber asi
 
Código Delphi [-]
      
if (not Eof)  then
 begin
  while not Eof do
   begin
     vCampos := vCampos + sc.Trim(oQTempCamposIndices.Fieldbyname('Campo').AsString) + ';';
      next;   
   end; 
 end
else
 Begin
  vCampos := vCampos + sc.Trim(oQTempCamposIndices.Fieldbyname('Campo').AsString);  
end;

Jere_84 15-06-2012 21:18:28

Cita:

Empezado por microbiano (Mensaje 435215)
Código Delphi [-]
      
if (not Eof)  then
 begin
  while not Eof do
   begin
     vCampos := vCampos + sc.Trim(oQTempCamposIndices.Fieldbyname('Campo').AsString) + ';';
      next;   
   end; 
 end
else
 Begin
  vCampos := vCampos + sc.Trim(oQTempCamposIndices.Fieldbyname('Campo').AsString);  
end;

Funciona pero pasa siempre por el lugar que concatena la coma a pesar de que halla uno o varios campos. La unica forma de diferenciarlo me parece a mi, seria con el RecordCount pero no se porque me tira error con esa tabla sys.columns no es un objeto valido..

microbiano 15-06-2012 21:24:09

ummm recordcount o lo que tienes en recordcount>0de ciertta forma es lo mismo que eof ya que validan si el query esta vacio, ahora el error que te marca es que no existe ese campo en la consulta que estas haciendo, es decir sys.columns no es valido. no forma parte de tu consulta.

Jere_84 15-06-2012 21:30:54

Cita:

Empezado por microbiano (Mensaje 435221)
ummm recordcount o lo que tienes en recordcount>0de ciertta forma es lo mismo que eof ya que validan si el query esta vacio, ahora el error que te marca es que no existe ese campo en la consulta que estas haciendo, es decir sys.columns no es valido. no forma parte de tu consulta.

La diferenica es que con el recordcount puedo hacer algo asi ya que devuelve un integer, en cambio eof es boolean..

Código Delphi [-]
If recordcount > 1 then
begin 
  //...
end
else
  //...

olbeup 15-06-2012 21:55:24

Hola Jere_84

Has repasado bien la SQL, la he realizado en mi ordenador y funciona correctamente, porque utilizas alias tan largos.

En vez de sys.columns AS Columnas, utiliza AS C, o algo parecido.

Código SQL [-]
SELECT
    C.name AS CAMPO
  FROM sys.columns AS C
    INNER JOIN sys.index_columns AS IC
      ON IC.object_id = c.object_id AND IC.column_id = C.column_id
    INNER JOIN sys.indexes AS I
      ON I.object_id = IC.object_id AND I.index_id = IC.index_id
  WHERE I.name = 'PKUC_IDEMPLEADO'

Un saludo.

Jere_84 15-06-2012 22:05:00

Cita:

Empezado por olbeup (Mensaje 435224)
Hola Jere_84

Has repasado bien la SQL, la he realizado en mi ordenador y funciona correctamente, porque utilizas alias tan largos.

En vez de sys.columns AS Columnas, utiliza AS C, o algo parecido.

Código SQL [-]
SELECT
    C.name AS CAMPO
  FROM sys.columns AS C
    INNER JOIN sys.index_columns AS IC
      ON IC.object_id = c.object_id AND IC.column_id = C.column_id
    INNER JOIN sys.indexes AS I
      ON I.object_id = IC.object_id AND I.index_id = IC.index_id
  WHERE I.name = 'PKUC_IDEMPLEADO'

Un saludo.

Hola olbeup, si la sentencia anda lo que si da un error en el RecordCount y no se porque. Voy a comprobar el tema de los alias pero no debería influir.

Casimiro Notevi 15-06-2012 22:26:51

No sé exactamente de qué va el hilo este, pero hay que tener en cuenta un 'pequeño' detalle:
recordcount no devuelve el número de registros involucrados en un query.
Habría que ir al último registro (hacer un fetch) para, ahora sí, usar el valor de recordcount.
Resumiendo:
Código Delphi [-]
qry.close;
qry.sql.text:='select nombre from tbclientes where provincia=28';
qry.execquery;
showmessage(inttostr(qry.recordcount));  //  <<---  Esto normalmente devolverá: 1

olbeup 16-06-2012 01:21:47

Cita:

Empezado por Casimiro Notevi (Mensaje 435226)
No sé exactamente de qué va el hilo este, pero hay que tener en cuenta un 'pequeño' detalle:
recordcount no devuelve el número de registros involucrados en un query.
Habría que ir al último registro (hacer un fetch) para, ahora sí, usar el valor de recordcount.
Resumiendo:
Código Delphi [-]
qry.close;
qry.sql.text:='select nombre from tbclientes where provincia=28';
qry.execquery;
showmessage(inttostr(qry.recordcount));  //  <<---  Esto normalmente devolverá: 1

Hola Casimiro,

Efectivamente te devuelve 1 registro
Código Delphi [-]
qry.close;
qry.sql.text:='select nombre from tbclientes where provincia=28';
qry.execsql;
showmessage(inttostr(qry.recordcount));  //  <<---  Esto normalmente devolverá: 1

Pero esto te devuelve cuantos registros hay
Código Delphi [-]
qry.close;
qry.sql.text:='select nombre from tbclientes where provincia=28';
qry.open;
showmessage(inttostr(qry.recordcount));  //  <<---  Esto devolverá: x registros
qry.close;

Un saludo

Casimiro Notevi 16-06-2012 09:56:10

Cita:

Empezado por olbeup (Mensaje 435238)
Pero esto te devuelve cuantos registros hay
Código Delphi [-]
qry.close; 
qry.sql.text:='select nombre from tbclientes where provincia=28'; 
qry.open; 
showmessage(inttostr(qry.recordcount));  //  <<---  Esto devolverá: x registros 
qry.close;

Un saludo

No, pruébalo y verás que no :)

Jere_84 16-06-2012 14:03:23

Cita:

Empezado por Casimiro Notevi (Mensaje 435249)
No, pruébalo y verás que no :)

Entonces andará mal tu Delphi, porque RecordCount devuelve la cantidad de registros. El nombre de la propiedad lo dice.

Slds.

Casimiro Notevi 16-06-2012 14:53:48

¿Lo has probado? :)

ecfisa 16-06-2012 21:34:39

Hola.

Cita:

Habría que ir al último registro (hacer un fetch) para, ahora sí, usar el valor de recordcount.
Casimiro tiene razón. Por otro lado la propiedad RecordCount no funciona bién en todas las bd.

Si tu intención es saber la cantidad de resultados que arrojó tu consulta:
Código Delphi [-]
  qry.SQL.Clear;
  qry.SQL.Text:= 'SELECT COUNT(*) AS CANTIDAD FROM TBCLIENTES WHERE PROVINCIA = 28';
  qry.Open;
  ShowMessage(qry.FieldByName('CANTIDAD').AsString);
  qry.Close;
O, si no te importa, podrías obtenerlo en una misma consulta GROUP BY mediante, pero te devolverá NOMBRE y CANTIDAD.

Saludos.

olbeup 17-06-2012 02:00:14

Cita:

Empezado por Casimiro Notevi (Mensaje 435249)
No, pruébalo y verás que no :)

Tengo muchas aplicaciones así y ninguna me ha fallado, trabajo con SQL SERVER 2005 y hasta ahora RecordCount se ha portado, sólo trabajo con ADOQuery, nunca he trabajado con ADOTABLE que también está el RecordCount, lo he probado muchas veces ADOQuery.RecordCount y devuelve los registros que contiene el ADOQuery, ni más ni menos.

Código SQL [-]
SELECT 
    COUNT(*) AS CANTIDAD 
  FROM TBCLIENTES 
  WHERE PROVINCIA = 28

Esta consulta es más rápida porque sólo devuelve un registro, pero tan válida cómo ADOQuery.RecordCount

Un saludo.

Casimiro Notevi 17-06-2012 02:07:49

Si el componente que estás usando tiene alguna propiedad del tipo "FetchAllRecords" y está a True, entonces es el motivo por el que te funciona el recordcount.
Pero ten en cuenta que eso es sólo por lo que he comentado, por el valor de una propiedad, ya que un select a una base de datos no puede saber cuántos registros involucra, salvo que vaya hasta el último, es algo elemental que verás en cualquier tutorial sql de cualquier base de datos.
Tenlo presente, y no te encabezones ;), RecordCount NO devuelve el número de registros. Salvo que sea una tabla plana, que no es el caso.


La franja horaria es GMT +2. Ahora son las 07:55:01.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi