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

 

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

πρόβλημα με procedure-δρομείς

Îåêßíçóå áðü ôï ìÝëïò Anastasia_M. Τελευταία δημοσίευση από το μέλος cap στις 14-02-2007, 03:29. Υπάρχουν 4 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  05-06-2006, 23:49 13687

    πρόβλημα με procedure-δρομείς

    Καλησπέρα.

    Έχω τον πίνακα REVIEW

     

    /*Table Review*/

    CREATE TABLE REVIEW(

    SCORE REAL CHECK (SCORE>=0 AND SCORE<=5),

    TEXT VARCHAR(MAX),

    DATE VARCHAR(25),

    CUSTOMER_ID INT ,

    LABEL VARCHAR(9) CHECK (LABEL IN('BAD','GOOD','VERY GOOD')),

    MOVIE_REVIEW VARCHAR(50),

    FOREIGN KEY(MOVIE_REVIEW) REFERENCES MOVIES(TITLE),

    FOREIGN KEY (CUSTOMER_ID) REFERENCES CUSTOMERS(ID)

    )

     

    με τις παρακάτω εισαγωγές

     

    INSERT

    INTO REVIEW(SCORE,TEXT,DATE,CUSTOMER_ID,LABEL,MOVIE_REVIEW)

    VALUES (1,'BLA BLA','1/6/06',6,'BAD','Munich')

     

    INSERT

    INTO REVIEW(SCORE,TEXT,DATE,CUSTOMER_ID,LABEL,MOVIE_REVIEW)

    VALUES (2,'BLA BLA','1/6/06',6,'BAD','Munich')

     

    INSERT

    INTO REVIEW(SCORE,TEXT,DATE,CUSTOMER_ID,LABEL,MOVIE_REVIEW)

    VALUES (3,'BLA BLA','1/6/06',6,'BAD','Munich')

     

    INSERT

    INTO REVIEW(SCORE,TEXT,DATE,CUSTOMER_ID,LABEL,MOVIE_REVIEW)

    VALUES (4,'BLA BLA','1/6/06',6,'BAD','Munich')

     

    INSERT

    INTO REVIEW(SCORE,TEXT,DATE,CUSTOMER_ID,LABEL,MOVIE_REVIEW)

    VALUES (5,'BLA BLA','1/6/06',6,'BAD','Munich')

     

    και θέλω να ενημερώνεται η στήλη  LABEL με βάση την τιμή που θα παίρνει κάθε φορά η στήλη SCORE από το χρήστη. (Η τιμή του SCORE διαρκώς θα αλλάζει). Χρησιμοποιώντας τη διαδικασία LABEL

     

    CREATE PROCEDURE LABEL

    AS

    DECLARE

    @LABEL VARCHAR(9),

    @SCORE INT,

    @BAD INT

     

    DECLARE LABEL_CURSOR CURSOR FOR

    SELECT SCORE,LABEL FROM REVIEW WHERE SCORE=@SCORE;

    OPEN LABEL_CURSOR;

         FETCH NEXT FROM LABEL_CURSOR

                            INTO @SCORE,@LABEL

    WHILE @@FETCH_STATUS = 0

       BEGIN

      FETCH NEXT FROM LABEL_CURSOR;

     

    UPDATE REVIEW

    SET LABEL='BAD'

    WHERE SCORE BETWEEN 1 AND 2;

     

    UPDATE REVIEW

    SET LABEL='GOOD'

    WHERE SCORE BETWEEN 3 AND 4;

     

    UPDATE REVIEW

    SET LABEL='VERY GOOD'

    WHERE SCORE=5;

     

    END;

     

    CLOSE LABEL_CURSOR

    DEALLOCATE LABEL_CURSOR

    GO

     

    EXEC LABEL

     

     η ενημέρωση γίνεται κανονικά αλλά υπάρχει ένα πρόβλημα. Ενώ ο πίνακας REVIEW έχει πέντε πλειάδες, στην εκτέλεση παραλείπεται η πρώτη.

     

    Μήπως μπορείτε να με βοηθήσετε να εμφανίζω και την πρώτη?

    Ευχαριστώ.

  •  06-06-2006, 08:07 13689 σε απάντηση της 13687

    Απ: πρόβλημα με procedure-δρομείς

    Μία μικρή παρατήρηση. Οι όροι "δρομείς" και "πλειάδες" δεν χρησιμοποιούνται. Φαντάζομαι ότι εννοείς cursors και tuples, αν και το tuples χρησιμοποιείται μόνο σε βιβλία σχεσιακής άλγεβρας, όχι SQL.

    Στην ερώτηση τώρα. Δεν υπάρχει κανένας λόγος να χρησιμοποιείς cursors ή triggers (όπως έκανες σε άλλη ερώτηση) για να κάνεις updates. Απλά δώσε τις εντολές κατευθείαν. Αντί να παίρνεις μία - μία εγγραφή και να κάνεις update ανάλογα με τις τιμές που έχει, δώσε τα updates κατευθείαν. Βέβαια, έτσι όπως έχεις γράψει το stored procedure συμβαίνει ακριβώς αυτό. Ανοίγεις μεν τον cursor αλλά δεν χρησιμοποιείς πουθενά τις τιμές που διαβάζει. Τα updates σου χρησιμοποιούν τα πεδία SCORE και LABEL, όχι τις μεταβλητές @SCORE και @LABEL.

    Χρησιμοποιώντας cursor τα updates γίνονται πιο αργά, όχι πιο γρήγορα. Αυτό γιατί κάθε βάση δεδομένων είναι φτιαγμένη για να κάνει μαζικές αλλαγές δεδομένων γρήγορα. Π.χ. αντί να αλλάζει τις τιμές μίας-μίας εγγραφής, μπορεί να χρησιμοποιήσει πολλαπλά threads για να τις αλλάξει παράλληλα, ή μπορεί να τις αλλάξει με άλλη σειρά (π.χ. τη σειρά με την οποία είναι αποθηκευμένες στο σκληρό δίσκο).
    Γενικά τα cursors πρέπει να τα αποφεύγεις όπως ο Devil το λιβάνι. Η χρήση τους είναι ένα από τα μεγαλύτερα προβλήματα που μπορεί να βρει κανείς σε μία βάση.

    Όσον αφορά την ερώτηση, αρκεί να γράψεις:


    UPDATE REVIEW
    SET LABEL='BAD'
    WHERE SCORE BETWEEN 1 AND 2;

    UPDATE REVIEW
    SET LABEL='GOOD'
    WHERE SCORE BETWEEN 3 AND 4;

    UPDATE REVIEW
    SET LABEL='VERY GOOD'
    WHERE SCORE=5;

    Και τελείωσες.
    Επίσης, αντί για REAL καλύτερα να χρησιμοποιήσεις τον τύπο NUMERIC. Ο REAL είναι floating point που σημαίνει ότι δεν ισχύει πάντα το 1 = 1! Αντίθετα, ο NUMERIC είναι δεκαδικός με συγκεκριμένη ακρίβεια.

    Πρέπει να έχεις υπόψη επίσης, ότι οι καθηγητές δεν εκτιμούν τις περίπλοκες λύσεις όταν αρκεί μία απλή. Τέτοιες ερωτήσεις σκοπό έχουν να δουν κατά πόσο ο φοιτητής κατάλαβε ότι η SQL δεν είναι μία συνηθισμένη γλώσσα, αλλά λειτουργεί σε set δεδομένων. Στην SQL λες στον υπολογιστή τί θες να κάνει και τον αφήνεις να το κάνει (UPDATE ... WHERE ...). Δεν του λες πως να το κάνει (π.χ. με cursor). Στη συγκεκριμένη περίπτωση, μια λύση με cursor μπορεί να δουλεύει αλλά δεν είναι η αναμενόμενη απάντηση.

     


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  06-06-2006, 21:37 13722 σε απάντηση της 13687

    Απ: πρόβλημα με procedure-δρομείς

    Καλησπέρα

    Σας ευχαριστώ πολύ για τις διευκρινίσεις που μου δώσατε, με βοήθησαν πάρα πολύ..

    Γνωρίζω ότι αυτό που θέλω να γίνει με τη παραπάνω διαδικασία γίνεται και ποιο εύκολα απλά με τις εντολές update, αλλά ήθελα να το προσπαθήσω με αυτόν το τρόπο...Και πάλι σας ευχαριστώ πάρα πολύ
  •  14-02-2007, 03:28 24972 σε απάντηση της 13687

    Απ: πρόβλημα με procedure-δρομείς

    Anastasia_M:

    DECLARE LABEL_CURSOR CURSOR FOR

    SELECT SCORE,LABEL FROM REVIEW WHERE SCORE=@SCORE;

    OPEN LABEL_CURSOR;

         FETCH NEXT FROM LABEL_CURSOR

                            INTO @SCORE,@LABEL

    WHILE @@FETCH_STATUS = 0

       BEGIN

      FETCH NEXT FROM LABEL_CURSOR;

    UPDATE REVIEW.....

    Κλασικό πρόβλημα. Σου έχω κάνει quote τα δύο FETCH NEXT που χρησιμοποιείς. Οταν μπαίνεις για πρώτη φορά στο loop, έχεις κάνει ήδη ΔΥΟ fetch next (ενα το εξωτερικό και ένα το εσωτερικό) πριν κάνεις το πρώτο σου update. Αρα, το update θα ξεκινήσει από τη δεύτερη εγγραφή του LABEL_CURSOR.

    Για να διορθωθεί, αρκεί να κάνεις το εσωτερικό FETCH NEXT μετά (και όχι πριν) τα UPDATE statements σου.

     


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

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  14-02-2007, 03:29 24973 σε απάντηση της 24972

    Απ: πρόβλημα με procedure-δρομείς

    Εεε, και για κάποιο χαζό λόγο δεν είδα οτι είχαν απαντήσει και άλλοι :) Αλλα παρ'όλα αυτά ισχύει η απάντηση :) Ο Παναγιώτης έχει δίκιο για τις μεταβλητές, αλλά εστιάζοντας στη χρήση του fetch next δεν το παρατήρησα. Προφανώς είχες δύο προβλήματα στο συγκεκριμένο :) (Και σταματάω να απαντάω γιατί στις 3.30 το πρωι οντως δεν βλέπω καλά :) ) - Παναγιώτη μην κοροϊδέψεις, γιατί θα ερθω και θα αντικαταστήσω όλα τα updates σου me cursors!

     

     


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

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems