begin process at 2012 02 13 15:01:18
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Base de Donnees

 > DECOMPOSITION SQL - ALGORITHME SIMPLE ET EFFICACE

DECOMPOSITION SQL - ALGORITHME SIMPLE ET EFFICACE


 Information sur la source

Note :
7 / 10 - par 1 personne
7,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Base de Donnees Classé sous :SQL, PARSE, DECOMPOSITION, ALGORITHME, ASIMENGO Niveau :Débutant Date de création :20/10/2008 Vu / téléchargé :5 778 / 369

Auteur : asimengo

Ecrire un message privé
Site perso
Commentaire sur cette source (8)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Une DLL qui permet de décomposer un texte SQL ou de jouer avec et d'avoir la décomposition de chaque Clause.

Pour mon utilisation perso je n'ai pas vraiment besoin de scruter le contenu de la clause From, raison pour laquelle la méthode utilisée pour le traitement de la clause From a des manquements et des limites. J'en ai plus besoin pour mon contrôle qui permet de visualiser des recordsets par passage des paramètres de CommandText et ConnectionString et Criteria.
De ce fait au lieu de Charger la Commande et après faire un .Filter=..., qui n'est pas optimisé je charge directement la commande ajustée sur les bons enregistrements.
Le problème également est que je dois compter les enregistrements, .MoveLast aprés .MoveFirst, il vaut mieux dans tous les cas avoir moins d'enregistrements à parcourir.

En réalité

J'ai ajouté à la propriété get SQL la possibilité de rajouter des valeurs dans les clauses WHERE, HAVING et ORDER BY de la SQL initiale.La propriété Let SQL permet de passer des paramètres jouant également sur les clauses citées plus haut.
On peut reinitialiser les critères et le tri.

L'algorithme utilisé est assez simple, le texte est préformaté en un passage de la chaine SQL et après la lecture devient aisé. Le principe de cette algorithme peut être réutilisé dans bien des cas.

Comme dab, vos commentaires seraient les bienvenus afin que je puisse optimiser le code.

Source

  • 'méthode Init de la Classe
  • Public Function Init(ByVal psSQL As String, _
  • Optional ByVal psLeftNameSeparator As String, _
  • Optional ByVal psRightNameSeparator As String, _
  • Optional ByVal psTextIdentificator As String)
  • If psLeftNameSeparator <> vbNullString Then msLeftNameSeparator = psLeftNameSeparator
  • If psRightNameSeparator <> vbNullString Then msRightNameSeparator = psRightNameSeparator
  • If psTextIdentificator <> vbNullString Then msTextIdentificator = psTextIdentificator
  • msSQL = TransformSQL(psSQL)
  • 'Pour mes besoins actuels, je ne joue qu'avec les instructions de la forme
  • ' SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...
  • ' au mieux avec TRANSFORM ... SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... PIVOT ...
  • Call ExtraitVariable("PIVOT", msPivot)
  • Call ExtraitVariable("ORDER BY", msOrderBy)
  • Call ExtraitVariable("HAVING", msHaving)
  • Call ExtraitVariable("GROUP BY", msGroupBy)
  • Call ExtraitVariable("WHERE", msWhere)
  • Call ExtraitVariable("FROM", msFrom)
  • Call ExtraitVariable("SELECT", msSelect)
  • Call ExtraitVariable("TRANSFORM", msTransform)
  • End Function
  • 'Propriétés de la classe
  • Public Property Get SQL(Optional ByVal psWhereCriteria As String, _
  • Optional ByVal psHavingCriteria As String, _
  • Optional ByVal psSort As String) As String
  • Public Property Let SQL(Optional ByVal psWhereCriteria As String, _
  • Optional ByVal psHavingCriteria As String, _
  • Optional ByVal psSort As String, ByVal psSQL As String)
  • Public Property Get SQLTransform(Optional ByRef psField As String, Optional ByRef psCaption As String) As String
  • Public Property Get SQLSelect(Optional ByRef psPredicate As String, Optional ByRef paFields As Variant, Optional ByRef paCaptions As Variant) As String
  • 'Propriété Get SQLFrom
  • 'paTables est un tableau des tables utilisées dans la SQL
  • 'paRelationShips est un tableau des relations
  • 'L'algorithme utilisée pour pour cette proprité a des limites certes mais permet de retrouver nos petits dans bien des cas
  • Public Property Get SQLFrom(Optional ByRef paTables As Variant, Optional ByRef paRelationShips As Variant) As String
  • Public Property Get SQLWhere() As String
  • Public Property Let SQLWhere(ByVal psSQLWhere As String)
  • Public Property Get SQLGroupBy(Optional ByRef paFields As Variant) As String
  • Public Property Get SQLHaving() As String
  • Public Property Let SQLHaving(ByVal psSQLHaving As String)
  • Public Property Get SQLOrderBy(Optional ByRef paFields As Variant) As String
  • Public Function ClearOrderBy()
  • Public Property Get SQLPivot(Optional ByRef psField As String, Optional ByRef paColumnsNames As Variant) As String
'méthode Init de la Classe
Public Function Init(ByVal psSQL As String, _
    Optional ByVal psLeftNameSeparator As String, _
    Optional ByVal psRightNameSeparator As String, _
    Optional ByVal psTextIdentificator As String)

    If psLeftNameSeparator <> vbNullString Then msLeftNameSeparator = psLeftNameSeparator
    If psRightNameSeparator <> vbNullString Then msRightNameSeparator = psRightNameSeparator
    If psTextIdentificator <> vbNullString Then msTextIdentificator = psTextIdentificator
    
    msSQL = TransformSQL(psSQL)
    
    'Pour mes besoins actuels, je ne joue qu'avec les instructions de la forme
    ' SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...
    ' au mieux avec TRANSFORM ... SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... PIVOT ...

    
    Call ExtraitVariable("PIVOT", msPivot)
    Call ExtraitVariable("ORDER BY", msOrderBy)
    Call ExtraitVariable("HAVING", msHaving)
    Call ExtraitVariable("GROUP BY", msGroupBy)
    Call ExtraitVariable("WHERE", msWhere)
    Call ExtraitVariable("FROM", msFrom)
    Call ExtraitVariable("SELECT", msSelect)
    Call ExtraitVariable("TRANSFORM", msTransform)
    
End Function

'Propriétés de la classe
Public Property Get SQL(Optional ByVal psWhereCriteria As String, _
    Optional ByVal psHavingCriteria As String, _
    Optional ByVal psSort As String) As String

Public Property Let SQL(Optional ByVal psWhereCriteria As String, _
    Optional ByVal psHavingCriteria As String, _
    Optional ByVal psSort As String, ByVal psSQL As String)

Public Property Get SQLTransform(Optional ByRef psField As String, Optional ByRef psCaption As String) As String

Public Property Get SQLSelect(Optional ByRef psPredicate As String, Optional ByRef paFields As Variant, Optional ByRef paCaptions As Variant) As String

'Propriété Get SQLFrom
'paTables est un tableau des tables utilisées dans la SQL
'paRelationShips est un tableau des relations
'L'algorithme utilisée pour pour cette proprité a des limites certes mais permet de retrouver nos petits dans bien des cas
Public Property Get SQLFrom(Optional ByRef paTables As Variant, Optional ByRef paRelationShips As Variant) As String

Public Property Get SQLWhere() As String

Public Property Let SQLWhere(ByVal psSQLWhere As String)

Public Property Get SQLGroupBy(Optional ByRef paFields As Variant) As String

Public Property Get SQLHaving() As String

Public Property Let SQLHaving(ByVal psSQLHaving As String)

Public Property Get SQLOrderBy(Optional ByRef paFields As Variant) As String

Public Function ClearOrderBy()

Public Property Get SQLPivot(Optional ByRef psField As String, Optional ByRef paColumnsNames As Variant) As String

 Conclusion

Pour aider cette DLL à retrouver les noms de tables dans la clause From, il vaudrait mieux que les tables dans la clause From soient des crochets ([...])

J'espère avoir des avis qui me permettront de voir les manquements et surtout de l'optimiser.

ASIMENGO

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture INTEGRATION AUTOMATIQUE DE LA ROULETTE/MOLETTE DE LA SOURIS ...
Source avec Zip GESTION DYNAMIQUE DES ITEMS - BIEN PLUS INTERESSANT QUE LES ...
Source avec Zip Source avec une capture DLL POUR EXECUTER LES FONCTIONS ET PROCEDURES EXTERNES A TON...
Source avec Zip Source avec une capture UTILISATION INTELLIGENTE DE WORD POUR REALISER LES ETATS
Source avec Zip Source avec une capture REQUETEUR DE BASE DE DONNEES TRES SIMPLE D'UTILISATION ET TR...

 Sources de la même categorie

Source avec Zip Source avec une capture BIEN ADMINISTRER LES ETUDIANTS ET LEURS CÔTES par okosa
Source avec Zip VBA EXEL GESTION DE PERSONEL NOUVEAU CONTRAT DE TRAVAI par oudlarbi
Source avec Zip Source avec une capture CREATION D'UN OBJET D'ACCÈS AUX DONNÉES par okosa
Source avec Zip Source .NET (Dotnet) MISAHORAIRE par MdelM
Source avec Zip Source avec une capture BASEDEDONNEES,GESTIONDEMALADES,DATABASSE par shadkitenge

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture APPLICATION_GRAPHE_DIJSTRA_PRIM_COLORATION_CODE2.0 par Donald180v
PARSE PDF AVEC ITEXTSHARP (RÉCUPÉRATION DU TEXTE, PAS OCR) par Norres
Source avec Zip Source .NET (Dotnet) DECOMPOSITION EN SOMME DE NOMBRES PREMIERS par alpha5
Source avec Zip Source avec une capture ACCESS 2010 GESTION D'UNE BIBLIOTHÉQUE par mondaying
Source avec Zip Source avec une capture Source .NET (Dotnet) UTILISATION DE BAZSOCKET , DU COMPOSANT MYSQL , TOUT CECI DA... par wiifeet

Commentaires et avis

Commentaire de vladam le 21/10/2008 09:43:09 administrateur CS

heu ..... mais ou est l'intérêt ?
ou je n'ai peut-être pas tout compris

Commentaire de asimengo le 21/10/2008 11:48:16

@Vladam: C'est sûr tu n'as rien compris. Je t'explique.

Moi je travaille avec des composants independants, ce qui suppose qu'à la base il ne sait pas quel paramètre il recevra. Alors pour mon composant permettant d'afficher les données d'une base de données, il recoit en paramètres la SQL (CommandText) et la connectionString. Maintenant supposons que nous avons un combo dont la sélection entraine un filtre de la liste.
Solution evidente, tu me diras de mettre des indicateurs dans la SQL de la liste à afficher de facon à former facilement la SQL filtrée. MAis dans mon cas il s'agit d'un composant indépendant qui ne sait pas à priori le contenu de la SQL.
Autre méthode si la liste est dans un datagrid, il suffit de lier le datagrid.datasource au Recordset resultant de la commande et apres de faire un filter. Super ca marche mais lorsque la liste à afficher sans filtre contient 30 000 enregistrements alors on comprend vite qu'il y'a un problème.
Mon composant permet de jouer avec la SQL et la liste est optimale.
Il suffit pour moi de definir la methode Init pour passer la SQL, Criteria definir une condition et la méthode Requery et tout est propre et bien.

De même comme dans mon cas si tu dois permettre à l'utilisateur de choisir les champs visibles, definir son tri et definir ses filtres. A moins de connaitre explicitement la SQL ce n'est pas evident.
Eh bien j'ai egalement un composant qui recoit en parametres une SQL, pour t'afficher un form avec onglets (Colonnes, Tri, Fitre) libre à l'utilisateur de bidouiller après le composant peut renvoyer la SQL resultat ou tous les paramètres afin que le programmeur en fasse ce qu'il veut.

Ca devrait être déjà assez clair à ce niveau je crois.

Commentaire de vladam le 21/10/2008 14:24:45 administrateur CS

en effet, c'est plus claire.
Je comprends mieux l'utilité de ton code.
Personnellement, j'aurais plutôt utilisé une architecture basée sur l'implémentation d'interce pour rester générique et adaptable, mais ta solution est défendable aussi.

Commentaire de asimengo le 22/10/2008 11:45:04

@Vladam: Je n'ai pas bien compris, en effet je ne cherches qu'à savoir plus si tu pouvais être plus explicite. Je profite également pour ajouter un autre intérêt de la decomposition SQL c'est de pouvoir ajouter/modifier des légendes ou les traduires dans une langue. Il suffira de rajouter des mots clés et après avoir identifier les captions, lire dans une table dictionnaire pour traduire en fonction de la langue choisie au démarrage de l'applis.

Je profite pour corriger un manquement dans la fonction TransformSQL
Remplacer "bParenthesisOpen As Boolean" par "lParenthesisOpen As Long"
et dans le corps de la procédure on aura plutôt
                Select Case sCar
                    Case "(": lParenthesisOpen = lParenthesisOpen + 1
                    Case ")": lParenthesisOpen = lParenthesisOpen - 1
                    Case ",":
                        If (Not bNameBegin) And (lParenthesisOpen = 0) Then
...

NB :
Le but de cette source n'est pas de vérifier la validité d'une SQL mais de la decomposer en supposant qu'à l'origine elle est valide. Sa grande utilité est de permettre l'optimisation des resultats de recordset.
Pour mon utilisation j'ai 2 méthodes la méthodes Refresh qui va faire un .Filter et un .Sort sur les variables sFiltre et sSort et la méthode Requery qui va reécrer la SQL en incluant sFiltre et sSort dans la SQL.

C'est dommage de ne pas avoir des retours d'utilisation qui bien évidemment permettent de faire évoluer le code et surtout d'avoir les mises à jour sinon certaines mises à jour ne se voient pas reloader.

Commentaire de EBArtSoft le 22/10/2008 12:57:05 administrateur CS

Je remercie asimengo pour perpetuer la tradition du VB6.
Et en plus c'est plutôt bien fait.

@+

Commentaire de asimengo le 22/10/2008 14:25:33

Merci EBARTSOFT, venant de toi c'est un grand compliment.

Commentaire de yan35 le 27/10/2009 02:22:27 7/10

Bonjour Asimengo et merci pour ce code.
Je viens de le tester car j'y trouve de l'intérêt notamment pour écrire plusieures requêtes qui se ressemblent et éviter de toutes les réécrire en assemblant les clauses similaires, par exemple la clause From qui peut être la même dans plusieurs recordsets qui eux se distingueraient par Select et Where, par exemple.
J'ai 2 remarques à faire : ton code ne fonctionne plus s'il y a des sous-requêtes inclues dans les différentes clauses ; tes séparateurs [ ] sont valables pour Access ou autres mais pas pour MySQL et sans doute d'autres SGBD.
Sinon je trouve dommage sur 284 téléchargements à cette date, personne ne t'a attribué de note.
Je mets 7/10 pour les remarques communiquées.
Cordialement

Commentaire de asimengo le 30/10/2009 16:22:26

@Yan35: Je précise bien dans le code que je m'intéresse uniquement aux syntaxes de la forme Transform ... select ... from ... where .... group by ... having ..., order by ... pivot ....
Le but n'est même pas de vérifier l'exactitude de la SQL, mais une décomposition dans le but de changer les paramètres des clauses.
Dans mon cas, j'ai un composant datagrid perso, qui permet d'afficher un recordset à partir de CommandText et de ConnectionString que j'utilise beaucoup pour afficher les tables filles, multi-requetage de liste, ...
Au lieu de charger toute la table et actualiser avec la méthode Filter qui rendrait le programme très lourd, j'ai besoin de passer à mon composant un critère externe. Mais les applications sont encore plus complexe, vu que je permet à chaque utilisateur d'avoir sa propre mise en forme de liste, disposition des colonnes et taille, c'est tout simple, je garde dans une table les valeurs de ColumnWithts, et la clause Select.

D'autre part la méthode Init permet de spécifier les délimiteurs de champs, par défaut c'est "[" et "]".

En déhors de l'aspect pratique de la source, l'algorithme utilisé est surtout le point important à assimiler.

A+

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Algorithme de compression LZW [ par PhiPhi ] Je recherche un algorithme de compression LZW pour une application non commerciale, si possible disponible en vb5.0 ou vb6.0 avec le code source.code connexion ODBC [ par nds ] Je voudrais appeler un etat crystal report7 (.rpt) à partir d'un controle activeX "CrystalReport" dans VB et pouvoir modifier le requete SQL qui alime Probleme requete SQL [ par steph ] Bonjour à touscomment faire dans une requete SQL pour sélectionner des enregistrements avec une clause WHERE faisant référence à une TEXTBOX du formul Connection SQL et RDO [ par Linda ] Bonjour !Voici mon problème.Dans SQL Server j'ai créé un role d'application.Je voudrais connecter mon application à ce rôle comment dois-je faire ?Mer combo sous access [ par presseb ] J'ai un probleme sous un formulaire access un combo fait appel a un champs d'une base de données SQLQuand je supprime a l'aide d'une requete sql des c Requete SQL [ par funtay ] bonjour, j'ai un problème de syntaxe dans une requete SQL.En fait ,j'ai une date de début (c'est un maskedbox( txt_datedeb)) et une date de fin (c'est Commande SQL LIKE avec Access [ par Valere ] Dans un script ASP j'interroge une base access avec une requete de type select * from MaTable Where MonChamp Like 't*' et je me retrouve avec un recor Compter les enregistrements d'une requete SQL [ par JCLK ] Je travaille habituellement avec ColdFusion, et j'ai du mal a transformer mes programmes en ASP.Je voudrais compter les enregistrements d'une requete ASP, SQL et champ DATE [ par idev ] En ASP avec une base Access, la requete suivante ne fonctionne pas. Erreur de syntaxe. Tout essayer mais je ne trouve pas la bonne syntaxe.SQL = "INSE Insérer un gif dans une base SQL [ par Sabrina ] J'utilise ASP pour afficher des gifs pomper sur une base SQL7, et j'aimerais insérer avec VB mes gifs dans cette base via ODBC ...Merci ...


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,562 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales