Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Μετατροπή SQL queries από/προς XML

Îåêßíçóå áðü ôï ìÝëïò defacer. Τελευταία δημοσίευση από το μέλος Παναγιώτης Καναβός στις 07-09-2007, 18:40. Υπάρχουν 4 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  07-09-2007, 11:50 34843

    Μετατροπή SQL queries από/προς XML

    Καλημέρα,

    Για τις ανάγκες μιας εφαρμογής στη δουλειά θα χρειαστεί να μετατρέψουμε ομάδες από SQL queries σε κάποιο parsable format και αργότερα να τα εκτελέσουμε σε κάποια database. Το πρόβλημα είναι ότι τα queries αυτά θα χρειαστεί να εισάγουν rows σε διαφορετικά tables, μεταξύ των οποίων υπάρχει relation. Για παράδειγμα έστω τα queries:

    INSERT INTO persons (name) VALUES ('Zaxarias');
    INSERT INTO telephones (personid, telephone) VALUES (###, '090123456');

    Το πρόβλημα εδώ είναι ότι στο δεύτερο query πρέπει να εισάγουμε ένα personid που είναι το id που πήρε ο νέος record στο table persons. Το format που θα επιλεγεί για την αναπαράσταση αυτών των 2 queries θα πρέπει να έχει πρόβλεψη ούτως ώστε να αντικαθίσταται το personid με τη σωστή τιμή.

    Για τις ανάγκες της συζήτησης, παραθέτω ένα XML format που μου έρχεται αυτή τη στιγμή στο μυαλό και που θα ήταν ικανοποιητικό για το παραπάνω παράδειγμα:

    <queries>
      <query type="insert" table="persons" insertid="my_variable_name">
        <field name="name">Zaxarias</field>
      </query>
      <query type="insert" table="telephones">
        <field name="personid">$my_variable_name</field>
        <field name="telephone">090123456</field>
      </query>
    </queries>


    Με bold φαίνεται η υποστήριξη για τη δυνατότητα που μας χρειάζεται.

    Ξέρει κανείς αν υπάρχει κάποιο πρότυπο implementation για την περίπτωση αυτή, ή θα πρέπει να σχεδιάσουμε και να υλοποιήσουμε ένα κατάλληλο format για δική μας χρήση;


    Ευχαριστώ!

  •  07-09-2007, 12:35 34845 σε απάντηση της 34843

    Απ: Μετατροπή SQL queries από/προς XML

    Αυτό που περιγράφεις είναι σχετικά περίεργο, και φυσικά δεν υπάρχει καμμία υλοποίηση. Ίσως άν περιέγραφες γιατί θέλεις να το κάνεις αυτό να υπήρχε πολύ ευκολότερος τρόπος να το πετύχεις. Π.χ. μήπως σκέφτεσαι ότι έτσι θα μπορείς να χρησιμοποιήσεις το ίδιο SQL για διαφορετικές βάσεις? Μήπως θέλεις να στείλεις τα statemens σε άλλο μηχάνημα για εκτέλεση? Κάτι άλλο? Στις δύο παραπάνω περιπτώσεις υπάρχουν άλλοι, πολύ ευκολότεροι τρόποι να το πετύχεις.

    Αν αυτό που θέλεις είναι να δημιουργήσεις XML από το SQL statemnt, ουσιαστικά θέλεις ένα SQL parser από τον οποίο μετά θα δημιουργείς XML και άλλον ένα ο οποίος θα εκτελέσει το αποτέλεσμα του XML. Ευτυχώς/δυστυχώς, υπάρχουν SQL parsers αλλά δύσκολα θα βρείς κάποιον που να καλύπτει 100% τη διάλεκτο της SQL που θέλεις. Από εκεί και πέρα, υπάρχουν πιο δυνατοί parsers και πιο εύκολοι. Σε κάθε περίπτωση όμως θα πρέπει να μάθεις λίγο για το πως δουλεύουν. Δεν είναι δύσκολο, απλά μην περιμένεις να το κάνεις σε μία μέρα. Εξάλλου, αυτό που ζητάς είναι αρκετά εξεζητημένο οπότε νομίζω ότι θα πρέπει να δώσεις λίγο χρόνο.

    Χονδρικά, για να φτιάξεις τον parser που θέλεις χρησιμοποιείς ένα parser generator στον οποίο δίνεις μία γραμματική της γλώσσας εισόδου και κανόνες που θα εκτελέσει για να δημιουργήσει το αποτέλεσμα, όταν συναντάει συγκεκριμένες δομές στην είσοδο. Π.χ.  τί θα κάνει αν συναντήσει το SELECT ή το WHERE. Αυτή η ενέργεια μπορεί να είναι η δημιουργία ενός νέου κειμένου ή η εκτέλεση μίας εντολής. O parser που δημιουργείται χρησιμοποιεί τη γραμματική για να μεταφράσει το κείμενο που του δίνεις και να δημιουργήσει ένα parse tree με τη δομή του κειμένου. Μετά χρησιμοποιεί τους κανόνες για να δημιουργήσει την επιθυμητή έξοδο. Η XML είναι ουσιαστικά η αναπαράσταση ενός parse tree οπότε η μετατροπή από το parse tree σε XML είναι σχετικά απλή. Αυτό που χρειάζεσαι είναι να βρεις μία γραμματική για τη γλώσσα που θέλεις, και να ορίσεις τις εντολές που θέλεις να εκτελέσεις σαν αποτέλεσμα.

    Ένας αρκετά διαδεδομένος parser generator είναι ο ANTLR με υλοποιήσεις σε C++, C#, Java και με έτοιμες γραμματικές για PL/SQL και τουλάχιστον το SELECT του SQL Server 2000. Τα αρχεία που χρησιμοποιεί περιέχουν τόσο τη γραμματική όσο και τους κανόνες για την παραγωγή του αποτελέσματος, επιτρέποντας σου έτσι να φτιάξεις ιδιαίτερα ευέλικτους parsers.
    Μία άλλη λύση είναι ο GOLD Parser ο οποίος έχει μία έτοιμη γραμματική για ANSI SQL 89. Η διαφορά του από τον ANTLR είναι ότι αντί για τον ορισμό των κανόνων σε κείμενο, γράφεις τις μεθόδους που θα καλέσει ο parser όταν συναντήσει π.χ. το SELECT ή το WHERE. Αυτό είναι λίγο πιο εύκολο στην κατανόηση αλλά προφανώς, δεν είναι τόσο ευέλικτο.

    Αν ήδη ξέρεις από parsers μπορείς να δημιουργήσεις τον δικό σου, αλλά δεν είναι και η ευκολότερη δουλειά. Νομίζω ότι θα είναι ευκολότερο να κοιτάξεις πως δουλεύει π.χ. ο ANTLR και να τον χρησιμοποιήσεις. Θα είναι πολύ ευκολότερο να κάνεις αλλαγές στη γραμματική και την XML που δημιουργεί τροποποιώντας απλά τα αρχεία με τους κανόνες, παρά αν γράψεις και τροποποιείς όλο τον κώδικα με το χέρι.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  07-09-2007, 14:22 34850 σε απάντηση της 34845

    Απ: Μετατροπή SQL queries από/προς XML

    Κατ' αρχήν ευχαριστώ για τη λεπτομερή σου απάντηση!

    Ο λόγος για τον οποίο θέλω να γίνει έτσι είναι ότι α) τα statements όντως θα πάνε σε άλλο μηχάνημα για εκτέλεση, β) όχι μόνο σε ένα, αλλά σε πολλά, γ) θα πρέπει να διατηρούνται βέβαια σωστά τα relations ανάμεσα στα tables. Ένα INSERT στη μία βάση μπορεί να πάρει αυτομάτως id (primary key) π.χ. 300 ενώ σε μια άλλη βάση να πάρει 305. Το επόμενο query που θα εκτελεστεί σε όλες τις βάσεις, πρέπει να περιέχει το σωστό id σε κάθε περίπτωση. Οπότε δεν μπορούμε να το κάνουμε hardcode, ούτε βέβαια να το γνωρίζουμε πριν έρθει η ώρα να εκτελεστούν τα queries.

    Εννοείται πως όλες οι βάσεις στις οποίες θα εκτελεστούν τα query έχουν την ίδια ακριβώς δομή, δεν έχουν όμως μέσα τα ίδια δεδομένα (ούτε καν την ίδια ποσότητα δεδομένων).

    Νομίζω ότι στην προκειμένη περίπτωση είναι overkill να χρησιμοποιήσω parser generator με δική του formal grammar. Ειδικά από τη στιγμή που για τις ανάγκες της εφαρμογής θα χρειαστεί ένα πολύ μικρό υποσύνολο της SQL, και ένας λόγος παραπάνω που τα queries που θέλουμε να κάνουμε "serialize" θα είναι πολύ συγκεκριμένα, η προφανής λύση είναι να γράψω parser μόνος μου.

    Απλά ήθελα να αποφύγω να ξανα-ανακαλύψω τον τροχό, ιδιαίτερα αφού η εμπειρία μου σε .NET είναι πολύ περιορισμένη (το background μου είναι σε hardcore c++ καταστάσεις).

    Και πάλι ευχαριστώ για το χρόνο σου.
  •  07-09-2007, 15:15 34852 σε απάντηση της 34843

    Απ: Μετατροπή SQL queries από/προς XML

    defacer:
    Καλημέρα,
    INSERT INTO persons (name) VALUES ('Zaxarias');
    INSERT INTO telephones (personid, telephone) VALUES (###, '090123456');


    Μήπως μπορείς να ακολουθήσεις μια λογική όπως:
    INSERT INTO persons (name) VALUES ('Zaxarias');
    INSERT INTO telephones (personid, telephone) select person id, '090123456' from persons where name='zaxarias'

    Εννοειται φυσικά πως μπορείς να απομονώσεις την εγγραφή που μόλις έκανες insert. Αν στο select πας και μέσα από index θα βγει και γρηγορα



    Manos
  •  07-09-2007, 18:40 34856 σε απάντηση της 34850

    Απ: Μετατροπή SQL queries από/προς XML

    Αυτό που περιγράφεις είναι ακριβώς το σενάριο του replication. Το κοίταξες? Όσον αφορά τα statements, μπορείς άνετα να γράψεις τα SQL statements έτσι ώστε να μην βασίζονται σε hard-coded τιμές. Μπορείς να χρησιμοποιήσεις τις συναρτήσεις @@IDENTITY, SCOPE_IDENTITY και στον SQL 2005 το OUTPUT clause για να επιστρέψεις το τελευταίο ID που δημιουργήθηκε σε ένα πίνακα. Μπορείς άνετα να φτιάξεις τα κατάλληλα statemens και να τα στείλεις σε άλλες βάσεις, αν και με το replication αυτό μπορεί να γίνει αυτόματα. Η χρήση της XML δεν σου προσφέρει κάτι.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems