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

 

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

Dynamic SQL generation is not supported against multiple base tables

Îåêßíçóå áðü ôï ìÝëïò Thiseas. Τελευταία δημοσίευση από το μέλος KelMan στις 15-10-2007, 08:57. Υπάρχουν 18 απαντήσεις.
Σελίδα 1 από 2 (19 εγγραφές)   1 2 >
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  11-10-2007, 17:45 36150

    Dynamic SQL generation is not supported against multiple base tables

    Με το SqlCommandBuilder σε C# (καλά... όχι μόνο σε C# - υπάρχει κι άλλη μια.... δεν θυμάμαι πως τη λένε!! Stick out tongue) μπορείς να μετατρέψεις ένα SQL SELECT στα αντίστοιχα UPDATE, INSERT, DELETE commands.
    Δυστηχώς αυτό δεν δουλεύει στο ADO.NET αν το SQL SELECT έχει κάποιο Join.
    Βγάζει το μύνημα:

    "Dynamic SQL generation is not supported against multiple base tables"

    Εγώ όμως θέλω παρ' ολο το join να φτιάξω αντίστοιχες SQL UPDATE, INSERT, DELETE για τον βασικό πίνακα.

    Ξέρει κάποιος φίλος κανένα work around για το πρόβλημα αυτό ή θα πρέπει να φτιάξω δικό μου parser?
    Μήπως έχει κάποιος φίλος κανα καλό link για parsers (free or not free) που να μου κάνουν την δουλειά αυτή έτοιμη?
    Μην ξαναεφεύρω τον τροχό...

    thnx!


    Παράδειγμα κώδικα που δουλεύει (console app):
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text;

    namespace cb
    {
    class Program
    {
    static void Main(string[] args)
    {
    const string connectionString =
    "Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True";

    using(SqlConnection connection = new SqlConnection(connectionString))
    {
    connection.Open();
    SqlCommand command = new SqlCommand("SELECT * from Customers", connection);
    SqlDataAdapter adapter = new SqlDataAdapter(command);

    SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

    DataSet dataset = new DataSet();
    adapter.Fill(dataset);

    string line = new string('-', 40) + Environment.NewLine;

    Console.WriteLine(command.CommandText);
    Console.WriteLine(line);


    Console.WriteLine(builder.GetUpdateCommand().CommandText);
    Console.WriteLine(line);
    Console.WriteLine(builder.GetDeleteCommand().CommandText);
    Console.WriteLine(line);
    Console.WriteLine(builder.GetInsertCommand().CommandText);
    Console.WriteLine(line);
    Console.ReadLine();
    Console.ReadLine();
    }
    }
    }
    }


    Αν την γραμμή 19 την κάνω
    SqlCommand command = new SqlCommand("SELECT Customers.customerID, orderID FROM Customers inner join Orders on (Orders.CustomerID =

    Δεν θα παίξει!!!


    Nothing to declare...
  •  11-10-2007, 18:10 36152 σε απάντηση της 36150

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Ναι, όντως δεν παίζει.. Δεν είναι θέμα workaround ή όχι, είναι καθαρά θέμα ότι δεν γίνεται και τόσο εύκολα να μαντέψει ο Builder τι query πρέπει να σου βγάλει το query με Join.
    Ο τρόπος είναι να τα γράψεις με το χέρι και να κάνεις assign εσύ εκεί που πρέπει. Τώρα δεν ξέρω εάν υπάρχουν "parsers" για τέτοιες δουλειές, αν και αμφιβάλλω καθώς όπως είπα το πρόβλημα είναι σύνθετο κι όχι τόσο απλό να υπάρχει μια generic λύση.
    Παναγιώτης Κεφαλίδης

    "Για να επιτύχεις, θα πρέπει το πάθος σου για την επιτυχία να είναι μεγαλύτερο απο τον φόβο σου για την αποτυχία"

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Παρακαλώ διαβάστε τους όρους χρήσης.
  •  11-10-2007, 18:21 36154 σε απάντηση της 36152

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Ναι... το ξέρω οτι δεν θα γινότανε με workaround,... απλά ήθελα να φτιάξω SQL queries για τον βασικό πίνακα (αν είναι πάνω από ένας)...
    Π.χ.
    Select *
    from X
    inner join Y....
    left outer join Z...
    κλπ...
    ο βασικός πίνακας είναι ο Χ. Τώρα βέβαια θα μου πεις ... αν γράψει κάποιος με τον παλιό τρόπο....
    Select *
    from X,Υ,Ζ...
    ποιός θα είναι ο βασικός πίνακας.... ας πούμε ο πρώτος.... Geeked ...
    Πολλά ζητάω ε?Smile

    Πάντως το BDP (Borland Data Provider) με την Borland 2005 παράγει "σωστό" update.... αλλά δεν είναι.... ADO Cool... κι εμείς είπαμε να "υοθετήσουμε" το ADO σαν τεχνολογία.

    Thnx anyway Παναγιωτη!!

    Edited:
    Πάντως Πάναγιώτη... Δεν νομίζω οτι είναι τόσο δύσκολη μαντεψιά...
    Μου φαίνεται λίγο περίεργο να μην μπορεί να το υποστηρίξει η Microsoft αυτό...
    Ρε φίλε (στην Micro$oft αναφέρομαι Cool ), αν δεν μπορείς να βρεις το βασικό πίνακα ζήτα το μου να στο περάσω σαν παράμετρο στην αντίστοιχη member function που θα έχεις...
    Μη μου πείς οτι μετά οτι δεν θα μπορούσε να βρεί τα columns που του αντοιστιχούν.... εδώ ολόκληρο SQL Server έφτιαξε....

    Δεν ξέρω.... αυτή η εταιρία... μερικές φορές σαν να το κάνει επίτηδες ρε παιδί μου.... να μας τυρανάει!!




    Nothing to declare...
  •  11-10-2007, 19:09 36155 σε απάντηση της 36154

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Μην περιορίζεις την σκέψη σου σε ένα απλό JOIN μόνο.. σκέψου λίγο πιο σύνθετα με παραπάνω απο 1 tables στο Join , nested selects και nested inserts και θα δεις ότι δεν είναι και τόσο "εύκολο" Smile
    Παναγιώτης Κεφαλίδης

    "Για να επιτύχεις, θα πρέπει το πάθος σου για την επιτυχία να είναι μεγαλύτερο απο τον φόβο σου για την αποτυχία"

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Παρακαλώ διαβάστε τους όρους χρήσης.
  •  11-10-2007, 19:42 36156 σε απάντηση της 36155

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Ακόμα και η απλή περίπτωση των πινάκων Χ, Υ, Ζ δεν είναι καθόλου απλή. Γιατί να θεωρούμε ότι ο Χ είναι ο βασικός πίνακας? Η σειρά των πινάκων σε ένα join δεν παίζει κανένα ρόλο. Δεν είναι δυνατόν από τη σειρά των πινάκων ή το ότι κάποιοι συνδέονται με inner join, να συμπεράνει κανείς ότι ένας από αυτούς είναι βασικός. Άσε, που αν το join δεν είναι στα primary keys, όχι ποιός είναι ο σωστός πίνακας δεν μπορείς να ξέρεις, αλλά ούτε καν ποιό είναι το σωστό row. Το ADO 2.0 σου επέτρεπε μέσω διαφόρων properties να κάνεις updates σε πολύ περιορισμένες περιπτώσεις. Αυτό δεν πέρασε στο ADO.NET γιατί δεν χρειάζεται.

    Υπάρχει απλούστερη λύση: Να φορτώσεις τους πίνακες σε ένα dataset, με το relation που θέλεις μεταξύ τους. Με τον τρόπο αυτό δεν υπάρχει καμμία ασάφεια ως προς το ποιοί πίνακες και ποιές γραμμές χρειάζονται updates. Άσε που έτσι φορτώνεις και σημαντικά λιγότερα δεδομένα.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  11-10-2007, 20:10 36157 σε απάντηση της 36156

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Χμ.... ναι σωστές όλες οι παρατηρήσεις.

    Σκεφτείτε όμως οτι υπάρχει ένας πίνακας ο οποίος γεμίζει με SQL statements δυναμικά, τα οποία δεν τα γνωρίζω από πριν, παρά μόνο στο runtime.
    Αυτά τα Select statements συνδέονται δυναμικά με ένα data grid στο οποίο (ακόμα και μένα απλό join), δεν μπορω να κάνω update....

    Φοβάμαι οτι τον parser δεν τον "γλυτώνουμε"...

    Nothing to declare...
  •  11-10-2007, 21:50 36160 σε απάντηση της 36157

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Φοβάμαι ότι βλέπεις το πρόβλημα μονοδιάστατα! Stick out tongue

    Όπως είπες και εσύ, το SQL δεν το ξέρεις παρά μόνο την στιγμή που θα σχηματιστεί και θα ζητήσει να εκτελεστεί. Επειδή και να φτιάξεις ένα τέτοιο parser, την στιγμή που ένα ανθρώπινο μυαλό δεν θα μπορεί να μαντέψει ακριβώς το κυρίως table ενός query όπως θα το δει έτοιμο, πως θα μπορέσεις να υλοποιήσεις ένα parser να το κάνει; Δεν έχω ακούσει για έτοιμο τέτοιο parser - τέτοιας μορφής που να κάνει αυτή την δουλειά, και πιστεύω ότι θα είναι δύσκολο να υλοποιηθεί.

    Οπότε σε συνέχεια των σκέψεων του Παναγιώτη, θα συνέχιζα ότι αυτό που θα πρέπει να υλοποιηθεί, θα μπορούσε να γίνει με βάση το αποτέλεσμα του query - να μπορέσεις να ξεχωρίσεις τα πεδία και τα tables από το αποτέλεσμα που θα επιστρέψει το query.

    Μια δεύτερη λύση στο πρόβλημα, αντί να πάμε ένα βήμα μετά και να αναζητήσουμε στο αποτέλεσμα του query τη λύση στο πρόβλημά μας, να πάμε ένα βήμα πίσω, και αντί να συνθέσουμε το SQL μας με τον πατροπαράδοτο τρόπο του concatenating, να σχηματίσουμε μια κλάση, που θα μπορεί με στοιχεία τα ονόματα των πεδίων των tables που θέλουμε να μας φτιάχνει το επιθυμητό query, και αφού έχουμε μια μηχανή που θα φτιάχνει το SELECT query μας, πόσο δύσκολο είναι να της δώσουμε και ένα hint για το κύριο table ώστε να μπορέσει με τα ίδια στοιχεία να φτιάξει και τα INSERT/UPDATE/DELETE queries;

    Έχοντας υλοποιήσει παρόμοιο μηχανισμό με το δεύτερο που περιγράφω, πιστεύω ότι είναι ο πιο στρωτός και σίγουρος δρόμος, και με εξασφαλισμένο το αποτέλεσμα και θα σου πρότεινα να τον ακολουθήσεις...

     

    George J.


    George J. Capnias: Χειροπρακτικός Υπολογιστών, Ύψιστος Γκουράρχης της Κουμπουτερολογίας
    w: capnias.org, t: @gcapnias, l: gr.linkedin.com/in/gcapnias
    dotNETZone.gr News
  •  11-10-2007, 22:40 36166 σε απάντηση της 36160

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Thnx για τις απαντήσεις, αλλά η εφαρμογή που το κάνει αυτό που ψάχνω σε .Net υπάρχει ήδη σε Delphi και δουλεύει αρκετά χρόνια,... απλά πρέπει να το μεταφέρω ή άλλες φορές να το ξαναγράψω.... σε C#.

    Καλώς ή κακώς η λειτουργικότητα με τα "άγνωστα" SQL queries πρέπει να μείνει ως έχει για διάφορους λόγους.... απλά παραπονιέμαι λίγο γιατί η Borland (όπως ήδη είπα) το έχει κάνει ήδη....

    Tespa....

    Thnx 4 your time again...

    Nothing to declare...
  •  12-10-2007, 08:48 36181 σε απάντηση της 36166

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Και στο .NET υπάρχει λύση. Για παράδειγμα το LLBLGen Pro, όταν έχει μια ιεραρχία από objects (πχ Customer με property collection από Orders που το κάθε Order έχει property με collection από OrderItems) παράγει τα κατάλληλα SQL Queries για CRUD operations. Εσύ απλά λες Fetch ή Update και όλα τα υπόλοιπα τα κάνει μόνο του Smile Από εκεί και πέρα, ο builtin ADO.NET μηχανισμός δεν παρέχει αυτή τη δυνατότητα αλλά έτσι κι αλλιώς ο CommandBuilder sucks big time καθώς ο κώδικας που παράγει είναι πολύ inefficient.


    Vir prudens non contra ventum mingit
  •  12-10-2007, 10:40 36189 σε απάντηση της 36181

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Ψάχνοντας βρήκαμε ένα πολύ ενδιαφέρον άρθρο για το θέμα: http://msdn2.microsoft.com/en-us/library/ms971491.aspx

    Παραθέτω ένα μικρό απόσπασμα:

    Okay, so it's tough to use the CommandBuilder when your SELECT queries get a bit more complex. What can you use instead? Well, there are lots of alternatives. What I've been doing lately is getting the DACW to help. To start with, I usually use stored procedures to perform both the SELECT and action queries. To setup a Command object to execute a stored procedure, you set the CommandText to the name of the stored procedure and the CommandType to CommandType.StoredProcedure—pretty much like ADOc.


    Nothing to declare...
  •  12-10-2007, 12:10 36193 σε απάντηση της 36189

    Απ: Dynamic SQL generation is not supported against multiple base tables

    To 2003 που γράφτηκε αυτό το άρθρο *ίσως* (και πάλι με μεγάαααλη επιφύλαξη) ήταν μια καλή λύση η one-size-fits-all stored procedure. Σήμερα, με όλα αυτά τα frameworks και τα ORMs που κυκλοφορούν,  δεν θα το έκανα με τίποτα...
    Vir prudens non contra ventum mingit
  •  12-10-2007, 12:31 36194 σε απάντηση της 36193

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Επιπρόσθετα, να σου πω Thiseas ότι αυτό που περιγράφεις, υποστηρίζεται από το engine της Borland (αλλά και από το παλιό ADO της Microsoft) για έναν και μόνο λόγο. Αυτά τα engines δουλεύουν σε connected mode. Συνδέονται στη βάση, τραβάνε τα data και κλειδώνουν, οπότε είναι πολύ εύκολο να καταλάβουν τι αλλαγές έχουν συμβεί και να περάσουν πίσω τις ενημερώσεις. Στο ADO.NET υπάρχει τεράστια διαφορά καθώς υπάρχει το disconnected μοντέλο που καθιστά πολύ δυσκολότερη αυτή τη δουλειά και η δυσκολία εντοπίζεται στο ότι πρέπει να κάνεις conflict resolution μιας και δεν είναι τίποτα δεδομένο για την κατάσταση των data από τη στιγμή που τα διάβασες μέχρι τη στιγμή που τα ενημερώνεις.


    Vir prudens non contra ventum mingit
  •  12-10-2007, 14:51 36201 σε απάντηση της 36194

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Θα πρέπει να πω οτι δεν καταλαβαίνω τι εννοείς ακριβώς λέγοντας connected mode....Embarrassed
    Είναι κάποιο definition που δεν γνωρίζω...? οπότε δεν μπορώ να καταλάβω καλά τι έχεις στο μυαλό σου λέγοντας αυτό....
    Μήπως εννοείς το statless level του internet? Αν ναι, εγώ δεν μιλάω για τέτοια εφαρμογή, αλλά μια C/S σε ένα LAN.

    Μήπως εννοείς το isolation level...? αυτό δεν έχει να κάνει με το ADO ή το BDE ...Κλπ κλπ

    Συμφωνώ με το Conflict Resolution. Πρέπει να πω όμως οτι έτσι που το θέτεις μοιάζει να είναι κάτι νεό....
    Το Conflict Resolution είναι πάρα πολύ παλιό θέμα και δεν είναι μόνο θέμα του ADO, της νέας υλοποίησης, προσέγγισης, τεχνολογίας όπως θες πες το. Να σου θυμίσω (χαριτολογόντας) οτι όλοι χροοονια ψάχνουμε αυτόν τον "Another User" που συνέχεια κάνει change το row όσο εγώ κάνω αλλαγές.... βλέπε isolation level: Commited Read Stick out tongue

    Τα Client Datasets, τα ApplyUpdates σε Remote Datamodules (ορολογία Borland) κλπ κλπ υποστηρίζονται πάνω απο 10 χρόνια.

    To πόσο είναι κάτι δεδομένο από τη στιγμή που διάβασες τα data μέχρι τη στιγμή που "αποφάσισες" να τα αλλάξεις δεν θα έλεγα οτι είναι θέμα ADO ή BDE, αλλά θέμα του Isolation Level που έχες επιλέξει.
    Αν έχεις επιλέξει Dirty Read (π.χ. Select * from Table1 with(nolock) ) τότε αυτό που θα διαβάσεις δεν ξέρεις καν αν θα έχει γίνει commit, είτε δουλεύεις ADO είτε BDE είτε είτε είτε...


    PS: Για να μην γίνει καμιά παρεξήγηση, μην νομίσει κάποιος οτι προσπαθώ να "περάσω" οτι η Borland έχει καλύτερη βιβλιοθήκη κλπ κλπ... άλλοστε αν πιστεύα 100% κάτι τέτοιο δεν θα είμουνα τώρα εδώ να κάνουμε αυτην την επικοδομιτική (πιστεύω) κουβέντα, ούτε θα σπαταλούσα τόσες ώρες για την τεχνολογία της MS.



    Nothing to declare...
  •  12-10-2007, 15:01 36203 σε απάντηση της 36201

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Αλλο πράγμα το isolation mode και άλλο το connected/disconnected model (και όχι mode).

    Αυτό που πρεσβεύει το disconnected model είναι το εξής: Συνδέομαι - κάνω τη δουλειά μου - αποσυνδέομαι. Ετσι λοιπον για να δω π.χ. μια καρτέλα ενός πελάτη και για να τροποποιήσω κάτι σε αυτή γίνονται οι εξής κινήσεις:

    1. Συνδέομαι-τραβάω δεδομένα-αποσυνδέομαι.

    2. Εμφανίζεται η καρτέλα του πελάτη, κάνω τις αλλαγές μου, και πατάω οκ.

    3. Συνδέομαι-καταχωρώ τα δεδομένα-αποσυνδέομαι.

    Καθ'όλη τη διάρκεια του (2) δεν γνωρίζω τι άλλο έχει γινει σε αυτό το συγκεκριμένο πελάτη και από ποιόν, ούτε καν αν έχει η δεν έχει γίνει κάτι. Ο συγκεκριμένος πελάτης μπορεί μέχρι και να έχει διαγραφεί! Επισης το "συνδέομαι" και "αποσυνδέομαι" είναι εσωτερικές διεργασίες του μοντέλου και δεν έχει να κάνει με το αν εμείς έχουμε reference σε κάποιο connection.

    Ετσι λοιπόν αποκτά άλλο νόημα ο όρος "conflict resolution" στα πλαίσια αυτού του μοντέλου. Το connected μοντέλο, αντίστοιχα, θα βρισκόταν συνδεδεμένο καθ'όλη τη διάρκεια της διεργασίας, έτσι θα μπορούσε πολύ ευκολότερα να καταλάβει τι έχει γίνει όση ώρα εμείς βρισκόμασταν στο βήμα (2).

    Μανο διόρθωσέ με αν δεν τα είπα καλά κάπου.


    Σωτήρης Φιλιππίδης

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  12-10-2007, 16:20 36209 σε απάντηση της 36203

    Απ: Dynamic SQL generation is not supported against multiple base tables

    Α!!
    Μήπως εννοείτε αυτό?: http://www.mono-project.com/Writing_Connected_Mode_Testcases

    Αν εννοείτε τον εσωτερικό διαχωρισμό των modes των κλάσεων του ADO.NET
    ...τότε φοβάμαι οτι έχουμε ξεφύγει από το αρχικό post και δεν μιλάμε για το ίδιο θέμα... μιας και δεν μιλάω καν για in-memory data processing (που αφορούν το dissconected mode)...

    Επίσης πρέπει να πω οτι το ADO.NET δεν "λειτουργεί" μόνο σε Disconnected Mode.... Πως θα μπορούσε άλλοστε... Confused
    Το Dataset λειτουργεί μόνο σε Connected State Mode.... και είναι αυτό που χρησιμοποιώ στο παράδειγμα μου...

    Παράθεση:

    ADO.NET:
    Few of the classes which constitute the connected mode behavior are given below.

    • DataSet
    • DataTable
    • DataRow
    • DataColumn
    • DataRelation
    • DataView
    • DataAdapter

    The disconnected mode behavior is provided by the specific provider classes derived from the following common base classes.

    • Connection
    • Command
    • DataReader

    Nothing to declare...
Σελίδα 1 από 2 (19 εγγραφές)   1 2 >
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems