SQL Query (Dynamic?) Pour vérifier que chaque entrée d'historique a une correspondance

StackOverflow https://stackoverflow.com/questions/8889496

  •  29-10-2019
  •  | 
  •  

Question

J'ai une procédure stockée qui génère un numéro de flotteur aléatoire en tant que marqueur d'ID, et dès qu'il est appelé, il stocke le numéro aléatoire + .1 dans une table d'historique / journalisation, puis le résultat final est stocké avec le même aléatoire Numéro +.2 (en tant que séquenceur / trieur).

Existe-t-il un moyen facile d'interroger dynamique une colonne remplie de ces numéros de séquence (comme illustré ci-dessous) et de vérifier qu'il y en a un nombre uniforme (paires) afin de s'assurer facilement que la procédure stockée a toujours traité correctement?

1568.1
1568.2
8452.1
8452.2
9886.1
9886.2
5455.1
3682.1
3682.2
4857.1
4857.2

Dans les exemples de données ci-dessus, je voudrais une requête qui alerte la présence de 5455.1 car elle n'a pas de deuxième partie (5455.2) qu'il devrait toujours avoir, car ma procédure stockée enregistre une deuxième entrée avec les résultats de l'appel (succès ou échec).

Bien sûr, j'en ai besoin non seulement pour m'alerter que le problème / bizarrerie existe (car je pourrais simplement exécuter un compte sur la table et voir si le nombre est même pour le déterminer), je voudrais pouvoir sélectionner les décalages Je ne trie donc pas 10 000 lignes d'histoire / journaux pour trouver celui qui n'a pas de partenaire.

Était-ce utile?

La solution

Tout d'abord, votre clé d'identité ne doit pas être une colonne, elle devrait être deux. C'est-à-dire au lieu de

CREATE TABLE OneCol  (IDKey DECIMAL(6, 1) Primary Key);

Vous devriez avoir quelque chose comme:

CREATE TABLE TwoCol  
(
    IDRand INT, 
    PhaseID TINYINT
    Primary Key  (IDRand, PhaseID)
)

En supposant cela alors et en plus que l'anomalie spécifique que vous recherchez est un ID avec {phase = 1) mais pas de {phase = 2} correspondant à cette façon d'écrire la requête:

SELECT IDRand FROM TwoCol WHERE PhaseID = 1
EXCEPT
SELECT IDRand FROM TwoCol WHERE PhaseID = 2

Autres conseils

Désolé pour la longueur ici, mais j'espère que cela pourrait aider la prochaine personne qui arrive ...

Comme suggéré ci-dessus, je vais diviser l'ID aléatoire en deux champs - le premier avec l'ID aléatoire, et le second avec l'ID "phase". L'utilisation de l'instruction Sauft ci-dessus fonctionne pour retourner une liste d'IDA qui ont été démarrées (la phase 1 existe) mais manquent la deuxième phase / réalisation.

Cependant, comme je ne veux pas passer du temps à rechercher chaque débit individuellement, j'ai enveloppé l'instruction sauf dans une déclaration comme copiée ci-dessous. Cela me permet de contrôler quels champs sont réellement retournés.

SELECT randomid, phaseid, info, type, time
FROM history
WHERE randomid IN (
SELECT randomid FROM history WHERE phaseid = '1' 
EXCEPT 
SELECT randomid FROM history WHERE phaseid = '2'  
)

Remarque: Envelopper l'instruction Sauft comme je l'ai fait, la partie distincte (voir le lien ci-dessous) est ignorée car je spécifie pour sélectionner tous. De plus, je devrai améliorer ma plage de nombres aléatoires et / ou y ajouter un code de date afin d'éviter une duplication. Si jamais j'avais obtenu le même nombre aléatoire deux fois, et si l'un est terminé et un a échoué, celui qui a échoué (n'avait pas de phase 2) n'apparaîtrait pas dans les résultats de la requête de la déclaration sauf comme l'existence d'une phase d'achèvement correspondante satisfera la clause sauf. Il ne vérifie pas qu'il y a une phase d'achèvement pour chaque phase de départ, seulement qu'une phase d'achèvement avec un identifiant aléatoire correspondant existe.

Si j'avais un schéma de nombres mal randomisé qui a abouti à des doublons, je pourrais avoir 16 entrées dans le tableau avec le même ID aléatoire (disons que l'ID aléatoire est 1337). Le nombre pair d'entrées avec un débarras de 1337 aurait l'air bien même si j'ai peut-être simplement eu un nombre égal d'erreurs (vérifier un nombre uniforme d'entrées dans la base de données n'est vraiment pas un bon moyen de vérifier les erreurs maintenant que je pense Bien que je puisse compter le nombre d'ID de phase qui sont 1 et le comparer à un décompte de ceux avec un PID de 2 afin de vérifier les résultats de ma requête). Sur ces 16 entrées, disons que 6 ont été achevés correctement (phase 1 et phase 2), et les 4 autres avaient échoué d'une manière ou d'une autre. Étant donné qu'une entrée dans la base de données existait pour RID 1337 avec un PID de 2, aucune des 4 échecs n'apparaîtrait.

Merci de m'avoir pointé dans la bonne direction, Barry!

========================================================

Le lien suivant semblait aller un peu plus en profondeur avec les exemples d'expression de l'opérateur que les autres sites, bien qu'il soit plus ancien (statiung que seuls les résultats distincts sont retournés, par rapport à tous les résultats).

http://www.databasejournal.com/features/mssql/article.php/3602601/except-opérator-in-sql-server-2005.htm

========================================================

Général de Pinal Dave récapitulation de l'opérateur:

L'un des Jr. Le développeur m'a demandé il y a un jour, SQL Server a-t-il une opération similaire comme la clause MINUS dans Oracle.

Absolument, sauf la clause dans SQL Server est exactement similaire à l'opération moins dans Oracle. La requête sauf et la requête moins renvoie toutes les lignes de la première requête qui ne sont pas renvoyées dans la deuxième requête. Chaque instruction SQL dans la requête sauf et la requête moins doit avoir le même nombre de champs dans les ensembles de résultats avec des types de données similaires.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top