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

 

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

Πως θα πάρω το τελευταίο Id πίνακα?

Îåêßíçóå áðü ôï ìÝëïò gmlogic. Τελευταία δημοσίευση από το μέλος gmlogic στις 18-09-2006, 09:23. Υπάρχουν 43 απαντήσεις.
Σελίδα 1 από 3 (44 εγγραφές)   1 2 3 >
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  07-09-2006, 14:28 16407

    Geeked [8-|] Πως θα πάρω το τελευταίο Id πίνακα?

    Ξεκινάω ένα transaction κάνω insert ένα record μετά προσπαθώ να το διαβάσω το τελευταίο id του πίνκακα για να το βάλω σε άλλο

    πίνακα αλλά είναι κλειδομένο

    το κάνω ως εξής

    Dim da_Sql As DbDataAdapter = dataFactory.CreateDataAdapter()

    ' Create INSERT, UPDATE, and DELETE commands.

    Dim command_builder As DbCommandBuilder = dataFactory.CreateCommandBuilder() ' = da_Sql

    da_Sql.SelectCommand = command

    command_builder.DataAdapter = da_Sql

    command.Transaction = transaction

    '@

    'Try

    Select Case data_row_state

    Case DataRowState.Added

    da_Sql.InsertCommand = command_builder.GetInsertCommand()

    Case DataRowState.Modified

    da_Sql.UpdateCommand = command_builder.GetUpdateCommand()

    Case DataRowState.Deleted

    da_Sql.DeleteCommand = command_builder.GetDeleteCommand()

    End Select

    da_Sql.Update(Changes)

    ' Commit the transaction.

    transaction.Commit()

    Ευχαριστώ εκ των προτέρων


    George Matzouranis
  •  07-09-2006, 15:04 16408 σε απάντηση της 16407

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Τι εννοείς κλειδωμένο; Ο κώδικας που δείχνεις δεν κλειδώνει κάτι πάντως.

    Αυτό το άρθρο περιγράφει όλες τις λεπτομέρειες για το πρόβλημα και πως λύνεται σε sql server και access:

    http://msdn.microsoft.com/library/en-us/dnadonet/html/manidcrisis.asp?frame=true


    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  07-09-2006, 15:08 16409 σε απάντηση της 16407

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Από τον κώδικα δεν φαίνεται το πως προσπαθείς να διαβάσεις το τελεταίο ID. Tο auto-generated SQL statement που παράγει η GetInsert δεν επιστρέφει τις τιμές των identity columns. Αν χρησιμοποιείς κάποιο άλλο Command, τότε θα πρέπει να το εντάξεις στο ίδιο transaction.

    Πάντως χρειάζεται προσοχή γιατί το ότι βάζεις τις δύο εντολές σε ένα transaction δεν σου δίνει καμία εγγύηση ότι στο χρονικό διάστημα που θα μεσολαβήσει ανάμεσα στο διάβασμα του τελευταίου ID και στην εισαγωγή της νέας εγγραφής, κάποιος τρίτος δεν έχει προλάβει να κάνει σφήνα εισαγωγή εγγραφής (που σημαίνει ότι δεν θα έχεις πλέον το πραγματικά τελευταίο ID). Κάτι τέτοιο ίσως να έπαιζε σωστά μόνο σε Serializable isolation level αλλά τότε, κατά πάσα πιθανότητα, θα είχες να αντιμετωπίσεις locks και timeouts.


    Vir prudens non contra ventum mingit
  •  07-09-2006, 15:21 16410 σε απάντηση της 16407

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Πριν το commit θέλω να διαβάσω το Id του πίνακα παρέλειψα να το σημειώσω

    Πάντως Δημήτρη σε ευχαριστώ για το link

    Θα το μελετήσω

    Μάνο εφόσον έχω αρχίση το transact μπορεί και κάποιος άλλος να κάνει insert έαν δεν κανω εγώ commit?


    George Matzouranis
  •  07-09-2006, 15:25 16411 σε απάντηση της 16410

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Το link που σου αναφέρω λύνει και το πρόβλημα που αναφέρει ο Μάνος.

    Σε γενικές γραμμές αυτό που λέει είναι το εξής:

    da_Sql.InsertCommand.CommandText += "; SELECT * FROM TABLE WHERE IDCOLUMN = @@SCOPE_IDENTITY"

    Η μεταβλητή @@SCOPE_IDENTITY περιέχει το τελευταίο autoincrement value στο τρέχον transaction.
    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  07-09-2006, 15:32 16412 σε απάντηση της 16410

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Το τι μπορούν να κάνουν οι υπόλοιποι εξαρτάται από το isolation level του transaction. Το default isolation level είναι το ReadCommitted και από όλα τα isolation levels, μόνο το Serializable δεν επιτρέπει στους υπόλοιπους να κάνουν Insert. Ωστόσο αυτό έχει το τίμημά του γιατί σε αυτό το isolation level γίνονται εκτενή κλειδώματα και κατά συνέπεια τα statements εκτελούνται πιο αργά. Είναι overkill να χρησιμοποιήσεις αυτό το isolation level, καλύτερα να αναθεωρήσεις τον σχεδιασμό σου για το συγκεκριμένο πρόβλημα.


    Vir prudens non contra ventum mingit
  •  07-09-2006, 15:40 16413 σε απάντηση της 16411

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

     papadi wrote:
    Το link που σου αναφέρω λύνει και το πρόβλημα που αναφέρει ο Μάνος.

    Σε γενικές γραμμές αυτό που λέει είναι το εξής:

    da_Sql.InsertCommand.CommandText += "; SELECT * FROM TABLE WHERE IDCOLUMN = @@SCOPE_IDENTITY"

    Η μεταβλητή @@SCOPE_IDENTITY περιέχει το τελευταίο autoincrement value στο τρέχον transaction.

    Δημήτρη θα έλεγα, λύνεται το μισό πρόβλημα. Όχι το πως θα πάρει κανείς το τελευταίο identity αλλά το πως θα πάρει το identity που παρήγαγε το Insert command.


    Vir prudens non contra ventum mingit
  •  07-09-2006, 18:25 16420 σε απάντηση της 16413

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Δεν είναι έτσι. Η παρακάτω εντολή θα πάρει το σωστό identity, ακόμα και δυο χρήστες κάνουν ταυτόχρονο update.

    INSERT INTO MYTABLE (COL1, COL2) VALUES (1, 2); SELECT SCOPE_IDENTITY()

    Τουλάχιστον αυτό περιγράφει το άρθρο και όσο το έχω χρησιμοποιήσει, δουλεύει σωστά. Προσοχή, όχι SELECT @@IDENTITY, αλλά SELECT SCOPE_IDENTITY().

    Για περισσότερες λεπτομέρεις δείτε στα books online για την SCOPE_IDENTITY(): Returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.
    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  07-09-2006, 18:50 16421 σε απάντηση της 16413

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Δεν διαφωνώ ως προς το SCOPE_IDENTITY αλλά μάλλον δεν με κατάλαβες... Κοίτα αυτό το σενάριο/παράδειγμα:

    1. Ο xρήστης Α ξεκινάει το transaction του.
    2. Ο xρήστης Β ξεκινάει το transaction του.
    3. O xρήστης Α κάνει Insert στον πίνακα και του επιστρέφεται identity = 10.
    4. Ο χρήστης Β κάνει κι αυτός Insert και του επιστρέφεται identity = 11.
    5. O xρήστης Α κάνει Insert στον πίνακα χρησιμοποιώντας το identity = 10 που είχε διαβάσει.
    6. O xρήστης Β κάνει Insert στον πίνακα χρησιμοποιώντας το identity = 11 που είχε διαβάσει.
    7. Ο χρήστης Α κάνει commit.
    8. Ο χρήστης B κάνει commit.

    Το SCOPE_IDENTITY δουλεύει σωστά, την στιγμή που το διαβάζει ο χρήστης Α (βήμα 3) του επιστρέφει σωστή τιμή αλλά το θέμα είναι ότι μέχρι ο χρήστης Α να φτάσει στο βήμα 5, ένας άλλος χρήστης έκανε το βήμα 4 και πλέον το ID που έχει ο χρήστης Α δεν είναι πραγματικά το τελευταίο που είχε χρησιμοποιηθεί. Το πρόβλημα προκύπτει από την χρονική στιγμή που διαβάζει ο χρήστης Α το identity.

    Είναι άλλο πράγμα να το χρησιμοποιήσεις το identity αφού έχεις κάνει ένα insert απλά για να ενημερώσεις το UI και άλλο πράγμα να έχεις ένα transaction όπου θα το επαναχρησιμοποιήσεις παρακάτω έχοντας την εντύπωση ότι είναι το τελευταίο identity που έχει χρησιμοποιηθεί. Εκτός αν μιλάμε για single-user εφαρμογή οπότε δεν υπάρχει τέτοιο concurency πρόβλημα.

    Πάντως, αυτός είναι ένας χαρακτηριστικός λόγος για τον οποίο δεν πρέπει να χρησιμοποιεί κανείς τα identities αλλά τα surrogate keys για τέτοιες δουλειές.


    Vir prudens non contra ventum mingit
  •  07-09-2006, 19:10 16423 σε απάντηση της 16421

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Λοιπόν σε έχω χάσει τελείως με το παράδειγμα αυτό. Αν το identity που αναφέρεις στα βήματα 3 και 4 έχει διαβαστεί με ένα "INSERT INTO ...; SELECT SCOPE_IDENTITY()" τότε δεν υπάρχει περίπτωση να πάρεις λανθασμένο ID, ό,τι άλλα transactions και να τρέχουν την ίδια στιγμή. Μπορείς με ασφάλεια να το χρησιμοποιήσεις στη συνέχεια, εντός και εκτός transaction, για να εισάγεις π.χ. συνδεδεμένες εγγραφές σε άλλους πίνακες.

    Αν πάλι παίρνεις το identity με ένα "SELECT MAX(ID) FROM MyTable" τότε πας γυρεύοντας Smile

    Το δικό σου το σενάριο ποιο από τα δύο είναι; 'Η μήπως κάποιο τρίτο;


    Νατάσα Μανουσοπούλου
  •  07-09-2006, 19:18 16424 σε απάντηση της 16423

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Ελπίζω να μην τα έγραψα τσάμπα όλα αυτά αλλά απ'ότι κατάλαβα, αυτό που θέλει ο gmlogic είναι να κάνει insert σε έναν πίνακα και κατόπιν να χρησιμοποιήσει το *τελευταίο* id για να "το βάλει" σε έναν άλλον πίνακα και με το transaction προσπαθεί να κλειδώσει τον πρώτο πίνακα μέχρι να τελειώσει ώστε να μην κάνει insert κάποιος άλλος. Τουλάχιστον σε αυτό το συμπέρασμα οδηγήθηκα από την δεύτερη απάντησή του. Ε? Μήπως δεν κατάλαβα καλά;


    Vir prudens non contra ventum mingit
  •  07-09-2006, 19:48 16425 σε απάντηση της 16424

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Χμμμμμ.... Τώρα που ανέφερες το max(id), μήπως προσπαθούσε να διαβάσει με αυτόν τον τρόπο το id και γι αυτό ήθελε να κλειδώσει τον πίνακα; Μπορεί να είναι αυτό. Οπότε το πρόβλημα λύνεται με το SCOPE_IDENTITY. Κι εγώ τα έφραψα τσάμπα όλα αυτά...
    Vir prudens non contra ventum mingit
  •  07-09-2006, 23:57 16433 σε απάντηση της 16425

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Για να πάρεις το autoincrement πεδίο από κάποιο πίνακα χρησιμοποίησε την εντολή SELECT IDENT_CURRENT(‘ΟΝΟΜΑ_ΠΙΝΑΚΑ’)

    so simple..!!!

  •  08-09-2006, 02:43 16441 σε απάντηση της 16433

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Το θέμα είναι πως μπορώ να πάρω το τελευταίο ID ενός πίνακα. Το πιο σωστό είναι το IDENT_CURRENT γιατί η IDENTITY και SCOPE_IDENTITY αναφέρονται μόνο για την δικιά μας σύνδεση. Λέγοντας μόνο για την δικιά μας σύνδεση σημαίνει πως ακόμα και αν κάποιος προσθέση μία εγγραφή η IDENTITY και η SCOPE_IDENTITY δεν θα αναφέρονται στην καινούρια τιμή αλλά στην τελευταία που έχει δωθεί από την στιγμή που εμείς ανοίξαμε την σύνδεσή μας με τον server.

    Εάν τώρα θέλει να χρησιμοποιήσει την τιμή τις IDENTITY σε άλλο πίνακα επειδή έχει δημιουργήσει σχέση, τότε η χρησιμοποίηση της IDENT_CURRENT είναι η χειρότερη επιλογή.

  •  08-09-2006, 09:47 16446 σε απάντηση της 16433

    Απ: Πως θα πάρω το τελευταίο Id πίνακα?

    Κυρίες και κύριοι, η αρχική ερώτηση ήταν ότι θέλει να κάνει insert και μετά να πάρει το ID που μόλις δημιουργήθηκε για να κάνει insert και σε άλλους συνδεδεμένους πίνακες.

    Η απάντηση είναι να χρησιμοποιήσει την SCOPE_IDENTITY.

    Ας μην μπερδεύουμε τον άνθρωπο με όλες τις συναρτήσεις και μεταβλητές που έχουν να κάνουν με auto increment πεδία!
    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
Σελίδα 1 από 3 (44 εγγραφές)   1 2 3 >
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems