Announcement

Collapse
No announcement yet.

CHECK auf andere Tabelle

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • CHECK auf andere Tabelle

    Hallo. Ist es möglich ein Check in Bezug auf andere Tabelle zu machen? Konkrettes Beispiel:

    CREATE TABLE xxx (
    a Number(3,0) PRIMARY KEY,
    c Number(1,0))

    CREATE TABLE yyy (
    a Number(3,0) PRIMARY KEY,
    b Number(3,0) NOT NULL REFERENCES xxx(a),
    c Number(1,0) CHECK (...c > xxx.c bei xxx.a = yyy.b...)

    Hier muss yyy.c nur solche Zahl zulassen, die grösser als xxx.c ist - bei Gleichheit des Schlüssels xxx.a = yyy.b.

    Lässt sich das mit Check überhaupt realisieren? Wenn nicht, wie geht es anders?

    Danke für euere Bemühungen.

  • #2
    Ist es möglich ein Check in Bezug auf andere Tabelle zu machen?
    Nein. Ein Checkconstraint prüft immer nur auf eine Tabelle und innerhalb dieser nur auf eine Zeile.

    Wenn nicht, wie geht es anders?
    In einem Multiusersystem? Überhaupt nicht. Außer Du sperrst die komplette Tabelle xxx bei jedem Insert in yyy und prüfst dann manuell die Daten.

    Mit Datenbankconstraints kannst Du das nicht abbilden. Evtl solltest Du dein ER-Modell nochmal überdenken.

    Dim
    Zitat Tom Kyte:
    I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

    Comment


    • #3
      Gut. Folgende Aufgabenstellung, als Beispiel, wo ich nicht weiss, wie ich mein ER-Modell anders aufbauen soll:

      - Tabelle 1 speichert gerade Zahlen (Spalten: id, zahl)
      - Tabelle 2 speichert ungerade Zahlen (Spalten: id, zahl)

      - Tabelle 3 soll NUR die geraden Zahlen referenzieren, also:
      REFERENCE Tabelle1(id)

      - Tabelle 4 soll ALLE Zahlen referenzieren können, also sowohl aus Tabelle 1 wie auch 2.

      Was ich mir also überlegt habe, Tabelle1 und Tabelle2 in eine Tabelle zusammenzufassen. Tabelle 4 hat also dann kein Problem mehr, jedoch Tabelle 3, da sie nur gerade Zahlen referenzieren soll.

      Wie kann ich mein ER-Modell aufbauen? Danke für die Mühe.

      Comment


      • #4
        Du könntest Tabelle 4 mit 2 Spalten aufbauen. Eine Spalte referenziert Tabelle 1, die andere Spalte referenziert Tabelle 2. Dann muss allerdings die Anwendungslogik schauen welche der beiden Referenzen denn nun gesetzt ist...

        Ist zwar jetzt auch nicht das unglaublich bahnbrechende Design, aber zumindest würds funktionieren.

        Tabelle 3 hätte dann nur eine Referenz auf Tabelle 1

        Comment


        • #5
          Tabelle 4 soll ALLE Zahlen referenzieren können, also sowohl aus Tabelle 1 wie auch 2.
          Können oder müssen? Bei letzterem ist es einfach. Du machst einfach zwei FK jeweils auf Tabelle 1 und 2
          Falls es eine Oder Bedingung ist, hast Du ein Problem, denn das lässt sich nicht über Constraints abbilden und müsste manuell nachgebaut werden. Entweder per Trigger oder über Programmlogik. Beides wird dir früher oder später Dateninkonsistenzen einbringen sofern es sich um ein Multiusersystem handelt und Du die Tabellen nicht immer explizit für eine Transaktion sperrst.

          Was Du allerdings machen kannst ist, dass Du die Tabelle 1 und 2 zusammenlegst und in Tabelle 3 einen Check Constraint einführst, der nur Werte mit geraden Zahlen zulässt:
          Code:
          MOD(spalte,2)=0
          Dim
          Zitat Tom Kyte:
          I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

          Comment


          • #6
            Wenn er die Tabelle mit den gerade Zahlen über eine ID referenziert wird der Check contstraint wohl auch nicht funktionieren, weil er ja nur die ID hat und nicht den eigentlich Wert.

            Gibts da nicht irgendeine andere Möglichkeit die Logik die dahinter steckt anders abzubilden?

            Comment


            • #7
              Hallo Freunde, danke für euere Antworten. Aber mich befriedigt immer noch keine. Die Logik in das Programm integrieren - das ist eine Lösung, aber sicher nicht die, wie sie die Programmierer von Oracle gemeint haben. Ich denke, der Fall mit der Komposition von Tabellen ist kein seltener, daher soll es bestimmt eine Lösung geben, aber nur wo....

              ich danke euch für weitere Bemühungen mir bei dem Problem zu helfen - ist wirklich dringend.

              Comment


              • #8
                Originally posted by 1234567 View Post
                Hallo. Ist es möglich ein Check in Bezug auf andere Tabelle zu machen?
                Danke für euere Bemühungen.
                Hallo,

                ja, dass ist möglich, du musst es über eine Skalare Subquery realsiieren in deiner Prüfung. Anbei 2 Beispiele, du musst es für deinen Fal anpassen.

                Code:
                ALTER TABLE emp 
                	ADD CONSTRAINT ck_fk CHECK( 0 < (SELECT COUNT(1) 
                			FROM dept WHERE dept.deptno=emp.deptno) )
                
                
                Oder auch möglich :
                
                ALTER TABLE ORDER 
                	ADD CONSTRAINT ck_fk CHECK(    0 < (select count(1) from business_customer b 
                	      where b.cust_id=order.cust_id) OR 0 < (select count(1) from home_customer h 
                		  	where h.cust_id=order.cust_id)  )

                Gruss

                Comment


                • #9
                  Hallo dbwizard,

                  wenn ich so vorgehe wie du beschrieben hast, kommt der Fehler:

                  "Unterabfrage ist nicht zulässig".

                  Comment


                  • #10
                    Originally posted by 1234567 View Post
                    Hallo dbwizard,

                    wenn ich so vorgehe wie du beschrieben hast, kommt der Fehler:

                    "Unterabfrage ist nicht zulässig".
                    Hi,

                    Poste doch mal dein Statement


                    Gruss

                    Comment


                    • #11
                      TABELLE A:

                      ID
                      WERT

                      TABELLE B:

                      ID
                      ID_A <referenziert A.ID>

                      werden erstellt.

                      Danach folgt:
                      (B.ID_A soll nur auf A.ID verweisen, wenn A.WERT = 0)

                      ALTER TABLE B ADD CONSTRAINT abc
                      CHECK (0 < (
                      ...SELECT COUNT(*)
                      ...FROM A
                      ...WHERE A.WERT = 0 AND A.ID = B.ID_A))

                      Comment


                      • #12
                        In der Online-Hilfe (Oracle 9i) zu Check-Restriktionen heißt es unter anderem:
                        The condition of a check constraint can refer to any column in the table, but it cannot refer to columns of other tables.
                        Der erwähnte Fehler läßt sich mit dem Code von dbwizard nachstellen:
                        Code:
                        ALTER TABLE emp 
                        	ADD CONSTRAINT ck_fk CHECK( 0 < (SELECT COUNT(1) 
                        			FROM dept WHERE dept.deptno=emp.deptno) );
                        kuemmelchen

                        Comment


                        • #13
                          Originally posted by kuemmelchen View Post
                          In der Online-Hilfe (Oracle 9i) zu Check-Restriktionen heißt es unter anderem:

                          Der erwähnte Fehler läßt sich mit dem Code von dbwizard nachstellen:
                          Code:
                          ALTER TABLE emp 
                          	ADD CONSTRAINT ck_fk CHECK( 0 < (SELECT COUNT(1) 
                          			FROM dept WHERE dept.deptno=emp.deptno) );
                          kuemmelchen
                          Sorry, da war ich wohl etwas zu voreilig :-). ich referenziere auf folgenden Artikel :

                          http://www.dbazine.com/oracle/or-articles/tropashko8


                          Dort wird das vorgehen beschrieben, ist allerdings nicht *trivial*


                          Gruss

                          Comment

                          Working...
                          X