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

 

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

Αναφορά σε πεδίο πίνακα που δεν είναι κλειδί

Îåêßíçóå áðü ôï ìÝëïò Anastasia_M. Τελευταία δημοσίευση από το μέλος Anastasia_M στις 14-02-2007, 13:09. Υπάρχουν 6 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  13-02-2007, 19:42 24940

    Αναφορά σε πεδίο πίνακα που δεν είναι κλειδί

    Καλησπέρα..Προσπαθώ να βρω το εξής.Έχω τον πίνακα p1(a,b,c)με κυρίως κλειδί το a και τον πίνακα p2(d,e,f) με κυρίως κλειδι το d και θέλω το f να αναφέρεται στο πεδίο c του p1(δηλαδή κάθε φορά που θα γίνεται εισαγωγή πλειάδας στον p2 και θα πάει να καταχωρηθεί τιμή στο f να γίνεται ο έλεγχος αν η τιμή που πάει να μπει στο f υπάρχει ήδη ως τιμή του c στον p1-πιο απλά θέλω για κάθε τιμή που πάει να μπεί στο f να γίνεται έλεγχος αν υπάρχει η τιμή αυτό στο c ) μου φαίνεται κάτι ανάλογο με το foreign key  αλλά δν ειναι το ίδιο γιατί το c δν είναι κλειδί σωστά?γίνεται να έχω reference χωρίς foreign key?πως μπορώ να το γράψω αυτό σε sql κατά τη δημιουργία του πίνακα p2?ευχαριστώ πολύ

  •  13-02-2007, 23:14 24955 σε απάντηση της 24940

    Απ: Αναφορά σε πεδίο πίνακα που δεν είναι κλειδί

    Για να δώσουμε μια σωστή απάντηση χρειαζόμαστε την πληροφορία για το αν σου ζητείται να γράψεις ANSI SQL ή κάποια συγκεκριμένη διάλεκτο (π.χ. T-SQL του SQL Server). Ποιό RDBMS χρησιμοποιείς;

     


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

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  14-02-2007, 00:12 24964 σε απάντηση της 24940

    Απ: Αναφορά σε πεδίο πίνακα που δεν είναι κλειδί

    Υποθέτοντας οτι χρησιμοποιείς SQL Server, μπορώ να σου πω οτι μπορείς να κάνεις τα εξής:

    Αν έχεις UNIQUE index ή constraint στο πεδίο c τότε μπορείς να βάλεις foreign key constraint στο f.

    Αν δεν έχεις κάτι τέτοιο, τότε θα πρέπει να υλοποιήσεις ένα CHECK constraint. Δυστυχώς, ο SQL Server (αν φυσικά δουλεύεις με αυτό το RDBMS) δεν επιτρέπει subqueries του τύπου CHECK (f IN (SELECT [DISTINCT] p1.c FROM p1 )). Για να έχεις το αποτέλεσμα που θέλεις, θα πρέπει να φτιάξεις μια UDF (user-defined function) που να κάνει τον ίδιο έλεγχο και να τη χρησιμοποιήσεις στο CHECK constraint σου.

    Αν σε μπέρδεψα, ζητώ συγνώμη. Αναφέρομαι σε υλοποίηση για τον SQL Server. Αν τυχόν δουλεύεις ANSI SQL τότε μπορείς να υλοποιήσεις CHECK constraint με subquery. Ομως, για να μην πάω παρακάτω και τα κάνω ακόμα πιό περίπλοκα, θα περιμένω να μου πεις με τι ακριβώς δουλεύεις.

     

     

     


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

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  14-02-2007, 01:35 24967 σε απάντηση της 24964

    Απ: Αναφορά σε πεδίο πίνακα που δεν είναι κλειδί

    ναι θα χρησιμοποιήσω sql server 2005 και το c δν εχει κανενα περιορισμο τπτ απολυτως ειναι ετσι σκέτο...χωρις κανενα constraint tpt

  •  14-02-2007, 03:14 24971 σε απάντηση της 24967

    Απ: Αναφορά σε πεδίο πίνακα που δεν είναι κλειδί

    Ενας τρόπος να το κάνεις είναι ο παρακάτω (σε SQL Server 2000, προφανώς όμως ισχύει και για 2005):

    Ας υποθέσουμε οτι όλα τα πεδία a,b,c,d,e,f των p1, p2 είναι τύπου int για ευκολία. Επίσης ας υποθέσουμε (δεν παίζει ρόλο στο τέλος, απλά για το παράδειγμα) οτι τα primary keys a και d είναι identity (autonumber) πεδία.

    Ας κατασκευάσουμε τον πίνακα p1:

    CREATE TABLE [dbo].[p1] (
      a [int] IDENTITY (1, 1) NOT NULL ,
      b [int] NULL ,
      c [int] NULL
    ) ON [PRIMARY]
    GO

    (Σημείωση: Για να μην γίνει τεράστιο το post δεν βάζω και τα primary key constraints μια και δεν αφορούν το συγκεκριμένο θέμα)

    Εφόσον το c δεν έχει τίποτα επάνω του, ο μόνος τρόπος για να πάρουμε τις τιμές που περιέχει το C μοναδικά είναι να κάνουμε ένα

    SELECT DINSTINCT p1.c FROM p1

    Ετσι λοιπόν θα μπορούσαμε δυνητικά να κατασκευάσουμε τον δεύτερο πίνακα (που έχει τον έλεγχο στο πεδίο f) ως εξής:

    CREATE TABLE [dbo].[p2] (
      d [int] IDENTITY (1, 1) NOT NULL ,
      e [int] NULL ,
      f [int] NULL
    check (f in (SELECT DISTINCT p1.c FROM p1))
    ) ON [PRIMARY]
    GO

    Αλλα αυτό δεν παίζει! Θα πάρουμε τα εξής μηνύματα:

    Subqueries are not supported in CHECK constraints, table 'dbo.p2'.
    Column CHECK constraint for column 'f' references another column, table 'dbo.p2'.
    Invalid column 'c' is specified in a constraint or computed-column definition.
    Could not create constraint. See previous errors.

    Και είναι φυσικό, μια και "Subqueries are not supported in CHECK constraints". Αρα πρέπει να βρούμε έναν άλλο τρόπο να κάνουμε τη δουλειά μας. Ετσι, μπορούμε να φτιάξουμε μια UDF (user-defined function) ως εξής:

    CREATE FUNCTION [dbo].[myCheck] (@myparam int)
    RETURNS bit
    AS
    BEGIN
    DECLARE @retVal bit

    IF EXISTS (SELECT DISTINCT p1.c FROM p1 WHERE p1.c = @myparam)
    BEGIN
      SET @retVal =1
    END
    ELSE
    BEGIN
      SET @retVal =0
    END

    RETURN @retVal
    END

    Η οποία θα δέχεται ως παράμετρο μια τιμή και θα μας γυρνάει 1 αν η τιμή υπάρχει στο p1.c πεδίο ή 0 αν δεν υπάρχει. Φυσικά, η τιμή που θα της περνάμε θα είναι η τιμή του πεδίου f.

    Για να τη χρησιμοποιήσουμε στο CHECK constraint μας, φτιάχνουμε τον πίνακα p2 ως εξής:

    CREATE TABLE [dbo].[p2] (
      d [int] IDENTITY (1, 1) NOT NULL ,
      e [int] NULL ,
      f [int] NULL
    check (dbo.myCheck(f)=1)
    ) ON [PRIMARY]
    GO

    Με το check (dbo.myCheck(f)=1), σε κάθε εγγραφή που γίνεται insert ή update στον πίνακα p2 ελέγχεται μέσω της udf η τιμή του f για το αν υπάρχει στο πεδίο c του πίνακα p1.

    Φυσικά, όπως ανέφερα, αυτός είναι ο ένας τρόπος. Ο άλλος τρόπος είναι με τη χρήση triggers. Σταματάω όμως εδώ για τώρα μια και είναι αρκετά αργά :) Ελπίζω να μην σε μπέρδεψα πολύ!


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

    DotSee Web Services

    View Sotiris Filippidis's profile on LinkedIn

    DotNetNuke them!
  •  14-02-2007, 11:11 24982 σε απάντηση της 24940

    Απ: Αναφορά σε πεδίο πίνακα που δεν είναι κλειδί

    Anastasia_M:

    Καλησπέρα..Προσπαθώ να βρω το εξής.Έχω τον πίνακα p1(a,b,c)με κυρίως κλειδί το a και τον πίνακα p2(d,e,f) με κυρίως κλειδι το d και θέλω το f να αναφέρεται στο πεδίο c του p1(δηλαδή κάθε φορά που θα γίνεται εισαγωγή πλειάδας στον p2 και θα πάει να καταχωρηθεί τιμή στο f να γίνεται ο έλεγχος αν η τιμή που πάει να μπει στο f υπάρχει ήδη ως τιμή του c στον p1-πιο απλά θέλω για κάθε τιμή που πάει να μπεί στο f να γίνεται έλεγχος αν υπάρχει η τιμή αυτό στο c ) μου φαίνεται κάτι ανάλογο με το foreign key  αλλά δν ειναι το ίδιο γιατί το c δν είναι κλειδί σωστά?γίνεται να έχω reference χωρίς foreign key?πως μπορώ να το γράψω αυτό σε sql κατά τη δημιουργία του πίνακα p2?ευχαριστώ πολύ

    To ερώτημα είναι αν οι τιμές του πεδίου c είναι μοναδικές ή όχι. Αν είναι μοναδικές, μπορείς να βάλεις στο πεδίο c ένα unique constraint και τότε θα σου επιτραπεί να ορίσεις primary/foreign key σχέση μεταξύ των p1.c και p2.f (κι ας είναι primary key το p1.a).

    Τώρα, αν οι τιμές του πεδίου C δεν είναι μοναδικές αλλά έχεις την ανάγκη που περιγράφεις, μου μυρίζει προβληματική σχεδίαση της βάσης (εκτός αν μιλάμε για άσκηση). Προσωπικά ποτέ δεν μου έχει παρουσιαστεί η ανάγκη να κάνω κάτι τέτοιο... 


    Vir prudens non contra ventum mingit
  •  14-02-2007, 13:09 24994 σε απάντηση της 24982

    Απ: Αναφορά σε πεδίο πίνακα που δεν είναι κλειδί

    ευχαριστώ για την ιδέα θα προσπαθήσω να την εφαρμόσω..πρόκειται για κάποια άσκηση με συγκεκριμένα constraints κ το c δεν εχει κανέναν περιορισμό, ούτε είναι μοναδικό..

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