2011-08-11 5 views
0

Je me connecte à une base de données SQL à l'aide d'un automate et doit renvoyer une liste de valeurs. Malheureusement, l'automate a une mémoire limitée et ne peut récupérer qu'environ 5 000 valeurs à la fois, mais la base de données peut contenir jusqu'à 10 000 valeurs. En tant que tel, j'ai besoin d'un moyen de récupérer ces valeurs en 2 opérations. Malheureusement l'automate est limité dans la requête qu'il peut effectuer, et est limité aux seules commandes SELECT et WHERE, donc je ne peux pas utiliser LIMIT ou TOP ou quelque chose comme ça.Numérotation de lignes dans une vue

Existe-t-il un moyen de créer une vue et de numéroter automatiquement tous les champs de cette vue? Je pourrais alors interroger tous les dossiers < 5,000, suivi par une deuxième requête de < 10,000 etc?

Malheureusement, il semble que les vues ne prennent pas en charge la colonne d'identité, cela devrait donc être fait manuellement.

Quelqu'un a-t-il des suggestions? Ma seule option réaliste au moment semble être de créer 2 vues, l'une avec le premier 5 000 et 1 avec le 5000 suivant ...

J'utilise SQL Server 2000 si cela fait une différence ...

Répondre

0

Alors que le code fourni par Derek fait ce que j'ai demandé - les numéros i.e. chaque ligne de la vue, la performance pour ce qui est vraiment faible - environ 20 secondes au numéro 100 lignes. En tant que tel, ce n'est pas une solution réalisable. Une alternative consiste à numéroter les 5 000 premiers enregistrements avec un 1, et les 5 000 suivants avec un 2. Cela peut être fait avec 3 requêtes simples, et est beaucoup plus rapide à exécuter.

Le code pour le faire est la suivante:

SELECT TOP(5000) BCode, SAPCode, 1 as GroupNo FROM dbo.DB 
UNION 
SELECT TOP (10000) BCode, SAPCode, 2 as GroupNo FROM dbo.DB p 
WHERE ID NOT IN (SELECT TOP(5000) ID FROM dbo.DB) 

Bien que, comme l'a souligné Andriy M, vous devez également spécifier un tri explicite, pour assurer la vous ne manquez aucun enregistrement.

0

Il y a 2 solutions. Le plus simple est de modifier votre table SQL et d'ajouter une colonne IDENTITY. Si ce n'est pas une possibilité, vous devrez faire quelque chose comme la requête ci-dessous. Pour 10000 lignes, cela ne devrait pas être trop lent. Mais à mesure que la table grandit, elle deviendra de pire en pire.

SELECT  Col1, Col2, (SELECT COUNT(i.Col1) 
       FROM yourtable i 
       WHERE i.Col1 <= o.Col1) AS RowID 
FROM   yourtable o 
+0

Merci, Derek, alors que ça marche et que ça compte, ça prend 20 secondes pour compter 100 enregistrements sur ma base de données de test, donc ça ne marchera pas très bien avec 10 000 lignes! J'ai à la place trouvé un moyen de numéroter les premiers 5 000 avec un 1, et le second 5 000 avec un 2, nous pouvons alors interroger à la place. –

+0

Le code mentionné ci-dessus est la suivante: 'SELECT TOP (5000) BCode, SAPCode, 1 groupe no DE dbo.DB union SELECT TOP (10000) BCode, SAPCode, 2 comme groupe no dbo.DB à partir de p O WH ID D'IDENTIFICATION (SÉLECTIONNER TOP (5000) ID FROM dbo.DB) ' –

+0

Je suis content que vous ayez trouvé une solution - vous pouvez l'afficher en tant que" Réponse "distincte et accepter votre propre réponse afin que quiconque rencontrant ce problème verra votre solution finale. –

0

Une possibilité pourrait être d'utiliser une fonction avec une table temporaire comme

CREATE FUNCTION dbo.OrderedBCodeData() 
RETURNS @Data TABLE (RowNumber int IDENTITY(1,1),BCode int,SAPCode int) 
AS 
BEGIN 
    INSERT INTO @Data (BCode,SAPCode) 
    SELECT BCode,SAPCode FROM dbo.DB ORDER BY BCode 

    RETURN 
END 

et sélectionner cette fonction comme

SELECT FROM dbo.OrderedBCodeData() WHERE RowNumber BETWEEN 5000 AND 10000 

Je n'ai jamais utilisé cette production, en fait était juste une idée rapide ce matin, mais vaut la peine d'explorer comme une alternative plus propre?

+0

Merci Justin - cela semble fonctionner, mais nous avons décidé d'aller avec l'option que j'ai mentionnée dans mon message. Nous communiquons à la base de données à partir d'un automate, qui a un support très limité pour SQL. Je ne suis pas sûr qu'il supportera les appels aux fonctions DB. –

Questions connexes