WHERE con posición ordinal ...

14/01/2004 - 10:27 por Toni Rom | Informe spam
Tengo una tabla con millones de registros. Quiero acceder
a un conjunto de ellos de los cuales sólo conozco su
posición ordinal.

Querría realizar un recordset con sólo estos registros. O
sea, no me interesa cargar un recordset con todo y luego
acceder con, por ejemplo GetAbsolutePosition(), al rango
de registros requerido.

Algo similar a poder usar un Recno() de Dbase dentro de
la sentencia Where de creación del Recordset de datos.

Alguien sabe algo al respecto o tiene solucionado este
problema de manera similar.

Gracias de antemano.

Toni.

Preguntas similare

Leer las respuestas

#6 Toni Rom
14/01/2004 - 16:43 | Informe spam
Muchachos, vosotros partís de la base de que la base de
datos es mía y que puedo gestionar una columna Identify.

Pues no la base de datos existe y no es mía y la tengo
que atacar desde mi aplicación. Como es atacable vía ADO,
entonces en vez de ser una base de datos podría ser una
EXCEL que, al fin y al cabo, se acaba tratando igual con
un Recordset.

Mi misión es optimizar el Recordset in inicial sin tener
acceso a la estructura orígen que es predeterminada y
fuera de mi alcance y gestión.

Gracias de todos modos por el esfuerzo.

Toni.


Es verdad, no hay soluciones magicas no? pero a mi me ha


sido de mucha
utilidad este truco y lo aplique en todas las tablas no


solo para ello sino
hasta para buscar registros mas facil

por ej:

hay una tabla que tenemos que 5 campos hacen de clave


no, imaginate escribir
todo eso en un update jeje, por lo cual si conoces el


rowid (mi campo
identity) la cosa se transforma en muy simple y rapido a


la vez ;)

Salu2


Maximiliano Damian Accotto


"Adrian Garcia"


escribió en el mensaje
news:uE5$
Si, esta opcion es buena, pero hay que tener en cuenta




que puede llegar a
haber agujeros entre los numeros que genera el




identity.

Si tuvieses un identity podrias seleccionar un rango




de filas asi:

SELECT * FROM <<tabla>>
WHERE id BETWEEN @nroreg AND @nroreg + @cantreg

donde id es la columna identity, @nroreg el nro. de




fila que quieres
generar
y @cantreg la cantidad de filas que deseas traer.
Repito: esta opcion no es perfecta ya que puede haber




huecos en las filas
provocados por DELETE's y por transacciones fallidas,




trayendo una
cantidad
menor de filas que las esperadas.
Por otro lado esta opcion es muchisimo mas eficiente




que utilizar la
sentencia TOP (en varios ordenes de magnitud) siempre




y cuando tenga un
indice cluster (eso seria lo ideal) por esa columna.




La sentencia TOP hace
que SQL Server, en este caso, procese las millones




filas solo para luego
obtener las primeras n filas que le asignes. Este




problema se agrrava si
la
sentencia tiene una clausula de ordenamiento!.


Saludos
Adrian D. Garcia


"Maximiliano D. A." <maxi_accotto[arroba]speedy[.]com




[.]ar> wrote in
message
news:
> Mira, yo como truco en todas las tablas tengo un




Campo identity que me
ayuda
> mucho a hacer estas cosas, solo lo uso para eso ;)
>
> Salu2
>
> Maximiliano Damian Accotto
>
>
> "Toni Rom" escribió en el mensaje
> news:078701c3da80$92e228b0$
> Tengo una tabla con millones de registros. Quiero




acceder
> a un conjunto de ellos de los cuales sólo conozco su
> posición ordinal.
>
> Querría realizar un recordset con sólo estos




registros. O
> sea, no me interesa cargar un recordset con todo y




luego
> acceder con, por ejemplo GetAbsolutePosition(), al




rango
> de registros requerido.
>
> Algo similar a poder usar un Recno() de Dbase dentro




de
> la sentencia Where de creación del Recordset de




datos.
>
> Alguien sabe algo al respecto o tiene solucionado




este
> problema de manera similar.
>
> Gracias de antemano.
>
> Toni.
>
>






.

Respuesta Responder a este mensaje
#7 Toni Rom
14/01/2004 - 16:45 | Informe spam
Pues no. Tú partes de la base de que la base de datos es
mía y que puedo gestionar una columna Identify.

Pues no la base de datos existe y no es mía y la tengo
que atacar desde mi aplicación. Como es atacable vía ADO,
entonces en vez de ser una base de datos podría ser una
EXCEL que, al fin y al cabo, se acaba tratando igual con
un Recordset.

Mi misión es optimizar el Recordset in inicial sin tener
acceso a la estructura orígen que es predeterminada y
fuera de mi alcance y gestión.

Gracias de todos modos por el esfuerzo.

Toni.



No existe ninguna función en SQL Server que te


devuelva directamente el
número que ocupa un determinado registro dentro de un


conjunto de
resultados. Para eso hay determinados trucos (crear una


tabla de resultados
con un identity y preguntar por él como ese


identificador), pero en una
tabla de millones de registros puede resultar demasiado


costoso.

¿No tienes forma de preguntar por un registro a


través de algún campo
único?


Un saludo

-
"Sólo sé que no sé nada. " (Sócrates)

Por favor, responder únicamente al foro
Se agradece la inclusión de sentencias DDL


"Toni Rom" escribió en el mensaje
news:078701c3da80$92e228b0$
Tengo una tabla con millones de registros. Quiero acceder
a un conjunto de ellos de los cuales sólo conozco su
posición ordinal.

Querría realizar un recordset con sólo estos registros. O
sea, no me interesa cargar un recordset con todo y luego
acceder con, por ejemplo GetAbsolutePosition(), al rango
de registros requerido.

Algo similar a poder usar un Recno() de Dbase dentro de
la sentencia Where de creación del Recordset de datos.

Alguien sabe algo al respecto o tiene solucionado este
problema de manera similar.

Gracias de antemano.

Toni.


.

Respuesta Responder a este mensaje
#8 Adrian Garcia
14/01/2004 - 20:19 | Informe spam
Si, esta opcion es buena, pero hay que tener en cuenta que puede llegar a
haber agujeros entre los numeros que genera el identity.

Si tuvieses un identity podrias seleccionar un rango de filas asi:

SELECT * FROM <<tabla>>
WHERE id BETWEEN @nroreg AND @nroreg + @cantreg

donde id es la columna identity, @nroreg el nro. de fila que quieres generar
y @cantreg la cantidad de filas que deseas traer.
Repito: esta opcion no es perfecta ya que puede haber huecos en las filas
provocados por DELETE's y por transacciones fallidas, trayendo una cantidad
menor de filas que las esperadas.
Por otro lado esta opcion es muchisimo mas eficiente que utilizar la
sentencia TOP (en varios ordenes de magnitud) siempre y cuando tenga un
indice cluster (eso seria lo ideal) por esa columna. La sentencia TOP hace
que SQL Server, en este caso, procese las millones filas solo para luego
obtener las primeras n filas que le asignes. Este problema se agrrava si la
sentencia tiene una clausula de ordenamiento!.


Saludos
Adrian D. Garcia


"Maximiliano D. A." <maxi_accotto[arroba]speedy[.]com[.]ar> wrote in message
news:
Mira, yo como truco en todas las tablas tengo un Campo identity que me


ayuda
mucho a hacer estas cosas, solo lo uso para eso ;)

Salu2

Maximiliano Damian Accotto


"Toni Rom" escribió en el mensaje
news:078701c3da80$92e228b0$
Tengo una tabla con millones de registros. Quiero acceder
a un conjunto de ellos de los cuales sólo conozco su
posición ordinal.

Querría realizar un recordset con sólo estos registros. O
sea, no me interesa cargar un recordset con todo y luego
acceder con, por ejemplo GetAbsolutePosition(), al rango
de registros requerido.

Algo similar a poder usar un Recno() de Dbase dentro de
la sentencia Where de creación del Recordset de datos.

Alguien sabe algo al respecto o tiene solucionado este
problema de manera similar.

Gracias de antemano.

Toni.


Respuesta Responder a este mensaje
#9 Manuel Etcheto
14/01/2004 - 21:54 | Informe spam
Toni
Tal vez podrías hacer algo mas o menos así, a ver si te
sirve la performance:
CREATE Procedure MyTablaOrdinal(@prireg int, @ultreg int)
AS
SET NOCOUNT ON
DECLARE @tabla TABLE (norden int identity, campo1 int,
campo2 varchar(30))
SET ROWCOUNT @ultreg
INSERT INTO @tabla SELECT campo1, campo2 FROM tablaOrigen
SET ROWCOUNT 0
DELETE FROM @tabla WHERE norden < @prireg
SELECT * FROM @tabla
GO

Por supuesto si pides del 10 al 20 no es lo mismo que del
900010 al 900020, pero es algo...

Suerte
Manuel





Tengo una tabla con millones de registros. Quiero acceder
a un conjunto de ellos de los cuales sólo conozco su
posición ordinal.

Querría realizar un recordset con sólo estos registros. O
sea, no me interesa cargar un recordset con todo y luego
acceder con, por ejemplo GetAbsolutePosition(), al rango
de registros requerido.

Algo similar a poder usar un Recno() de Dbase dentro de
la sentencia Where de creación del Recordset de datos.

Alguien sabe algo al respecto o tiene solucionado este
problema de manera similar.

Gracias de antemano.

Toni.
.

Respuesta Responder a este mensaje
#10 Javier Loria
14/01/2004 - 22:15 | Informe spam
Hola Toni:
Lo que los companeros foreros tratan de decirte sin mucho exito es NO
EXISTE el concepto de posicion ordinal en un conjunto de datos, y por ende
SQL no lo tiene.
Los clientes, en este caso ADO toman los conjuntos de Datos y los llenan
en Arreglos (o en estructuras mas complejas basadas en arreglos) y ahi por
supuesto tendras un numero ordinal o indice para usar los datos.
El uso del Identity (un invento de Sybase) es un pobre sustituto del
numero ordinal que buscas y es EN MI OPINON (que difiere de la mayoria de
los miembros de este foro) un mal necesario cuando no has cambiado de forma
de pensar y te alejas de las estructuras de arreglos y empiezas a pensar en
conjuntos de datos, con algunas desventajas adicionales importantes.
Otra alternativa para no tener que cambiar de forma de pensar es usar
cursores, los cursores tienen precisamente como objetivo permitir el acceso
para que las aplicaciones clientes puedan construirse usando arreglos. Un
ejemplo es la forma en que Microsoft usa estos recursos es la forma en que
ADO, (el viejo) no el ADO.NET, usa estas alternativas.
Si en VB o en VBA usas algo como:
= Codigo en VB
= Dim cn As String
Dim sql As String
Dim rs As New ADODB.Recordset

cn = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security
Info=False;Initial Catalog=pubs;Data Source=."
sql = "SELECT * FROM Authors ORDER BY au_id"

rs.CacheSize = 5
rs.Open sql, cn, adOpenKeyset, adLockReadOnly
rs.AbsolutePosition = 15
' De aqui en adelante trabajas con la posicion 15 y ya estan
' en el cliente los siguientes 5 registros
== Este codigo te genera un comportamiento como el deseado se genera la
consulta pero solo viajan del servidor a la estacion los datos deseados. Si
deseas emular este comportamiento en sentencias de SQL (ejemplo un
procedimiento), podrias usar los procedimientos almacenados que MS usa para
esto, aun cuando no esten documentados. El codigo seria algo como:
=Codigo en SQL
ÞCLARE @P1 int, @P2 int, @P3 int, @P4 int
SELECT @P10150000, @P2=1, @P3=1,
@P4# -- Cursor KEYSET/READONLY

- Abre el cursor
EXEC sp_cursoropen @P1 output,
N'SELECT * FROM Authors order by au_id',
@P2 output, @P3 output, @P4 output

exec sp_cursorfetch @P1, 16, 1, 10

exec sp_cursorfetch @P1, 16, 20, 10
exec sp_cursorfetch @P1, 16, 1, 5
exec sp_cursorclose @P1
=
Por supuesto este codigo lo puedes incluir en un Procedimiento Almacenado
con parametros y listo.

Hasta aqui el limite de mis conocimientos sobre las alternativas de lo que
PUEDES hacer. Lo que creo que DEBES hacer es otra cosa ya que Microsoft
mismo en la nueva ADO.NET, se deshace de esta arquitectura y pasa a trabajar
con DataSets o sea CONJUNTOS DE DATOS, lo que obliga ahora a los
programadores a tambien en el cliente a cambiar de forma de pensar.

Espero te sirva el codigo, aunque preferiria te sirvan los comentarios.

Saludos,



Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

Toni Rom escribio:
Pues no. Tú partes de la base de que la base de datos es
mía y que puedo gestionar una columna Identify.

Pues no la base de datos existe y no es mía y la tengo
que atacar desde mi aplicación. Como es atacable vía ADO,
entonces en vez de ser una base de datos podría ser una
EXCEL que, al fin y al cabo, se acaba tratando igual con
un Recordset.

Mi misión es optimizar el Recordset in inicial sin tener
acceso a la estructura orígen que es predeterminada y
fuera de mi alcance y gestión.

Gracias de todos modos por el esfuerzo.

Toni.



No existe ninguna función en SQL Server que te devuelva
directamente el número que ocupa un determinado registro dentro de
un conjunto de resultados. Para eso hay determinados trucos (crear
una tabla de resultados con un identity y preguntar por él como ese
identificador), pero en una tabla de millones de registros puede
resultar demasiado costoso.

¿No tienes forma de preguntar por un registro a través de algún
campo único?


Un saludo

-
"Sólo sé que no sé nada. " (Sócrates)

Por favor, responder únicamente al foro
Se agradece la inclusión de sentencias DDL


"Toni Rom" escribió en el mensaje
news:078701c3da80$92e228b0$
Tengo una tabla con millones de registros. Quiero acceder
a un conjunto de ellos de los cuales sólo conozco su
posición ordinal.

Querría realizar un recordset con sólo estos registros. O
sea, no me interesa cargar un recordset con todo y luego
acceder con, por ejemplo GetAbsolutePosition(), al rango
de registros requerido.

Algo similar a poder usar un Recno() de Dbase dentro de
la sentencia Where de creación del Recordset de datos.

Alguien sabe algo al respecto o tiene solucionado este
problema de manera similar.

Gracias de antemano.

Toni.


.
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida