Announcement

Collapse
No announcement yet.

MS SQL 2000 Index

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

  • MS SQL 2000 Index

    Hallo zusammen,

    ich bräuchte dringend etwas Hilfe. Ist es möglich einen Index, eine Einschränkung oder irgend etwas auf einer Tabelle einzurichten welche folgende Einschränkung bietet:

    Ich habe 3 Spalten:

    <PRE>

    A B C

    </PRE>

    Ich möchte nun dass die eingetragenen Datensätze eindeutig sind. Nur müsste es so sein, dass entweder Null-Werte ignoriert werden, oder dass ich in der Spalte C nur bestimmte Werte betrachte.

    Z.B: sollte folgende Situation nicht möglich sein:
    <PRE>

    A B C

    1 1 1
    1 1 1 -> dürfte nicht eingetragen werden
    1 1 2

    </PRE>

    Z.B. folgende schon

    <PRE>

    A B C

    1 null 1
    1 null 1
    1 1 1
    1 null 1

    </PRE>

    Wenn es mit Null-Werten nicht möglich ist, dann wäre folgendes Nötig:

    Wenn in Spalte C der Wert 1 steht, dann müssen die Kombinationen aus Spalte A und B eindeutig sein, wenn C = 0 ist dann können auch die Spalten A und B mehrdeutig sein.

    Wenn jemand etwas darüber weiss, bitte helft mir.

    Danke

    Astner Klaus

  • #2
    Da fällt mir nur noch die Möglichkeit über Trigger ein (INSERT, UPDATE) in der du deine spezielle Logik implementierst. Ein (Unique-)Index ist so wie du ihn haben willst m.E. nicht möglich

    Comment


    • #3
      Hallo,

      das folgende Beispiel für den MS SQL Server (oder MSDE) demonstriert einen der möglichen Wege. Die Terminüberschneidung wird dabei über eine Tabelle umgesetzt. Eine Stored Procedure schaut zuerst über eine SELECT-Abfrage nach, ob es zu einer Überschneidung kommt. Wenn ja, wird die Stored Procedure sofort verlassen. Wenn nein, liegt die SP den neuen Datensatz an:
      <pre>
      --Testtabelle anlegen
      <b>CREATE</b> <b>TABLE</b> Termin (
      Terminnummer <b>INTEGER</b> <b>NOT</b> <b>NULL</b> <b>IDENTITY</b> <b>PRIMARY</b> <b>KEY</b>,
      Anwender <b>INTEGER</b>,
      Terminstart DATETIME,
      Terminende DATETIME,
      Termininfo <b>VARCHAR</b>(10))
      <b>GO</b>
      -- Testdatensatz anlegen
      <b>INSERT</b> <b>INTO</b> Termin (Anwender,Terminstart,Terminende,Termininfo)
      <b>VALUES</b> (100,<font color="#9933CC">'19.11.2003 09:00:00'</font>,<font color="#9933CC">'21.11.2003 12:00:00'</font>, <font color="#9933CC">'Meier'</font>)
      <b>GO</b>
      -- Gespeicherte Prozedur anlegen
      <b>CREATE</b> <b>PROCEDURE</b> spInsertTermin
      (
      @Anwender <b>INTEGER</b>,
      @Terminstart DATETIME,
      @Terminende DATETIME,
      @Termininfo <b>VARCHAR</b>(10)
      )
      <b>AS</b>
      <b>DECLARE</b> @Kollision <b>INTEGER</b>
      <b>SELECT</b>
      @Kollision = <b>COUNT</b>(*)
      <b>FROM</b>
      Termin
      <b>WHERE</b>
      Anwender = @Anwender <b>AND</b>
      (@Terminstart &gt;= Terminstart) <b>AND</b>
      (@Terminstart &lt;= Terminende)
      <b>IF</b> @Kollision &gt; 0
      <b>BEGIN</b>
      -- Termin ist belegt, sofort raus
      <b>RETURN</b> -1
      <b>END</b>
      <b>INSERT</b> <b>INTO</b> Termin (Anwender,Terminstart,Terminende,Termininfo)
      <b>VALUES</b> (@Anwender,@Terminstart,@Terminende,@Termininfo)
      <b>RETURN</b> @@rowcount
      <b>GO</b>
      -- Testfall 1: Terminüberschneidung
      <b>DECLARE</b> @iReturn <b>INTEGER</b>
      <b>EXEC</b> @iReturn = spInsertTermin 100, <font color="#9933CC">'20.11.2003 10:00:00'</font>,<font color="#9933CC">'20.11.2003 11:00:00'</font>,<font color="#9933CC">'TEst'</font>
      PRINT @iReturn
      -- Testfall 2: Termin ist ok
      <b>DECLARE</b> @iReturn <b>INTEGER</b>
      <b>EXEC</b> @iReturn = spInsertTermin 100, <font color="#9933CC">'25.11.2003 10:00:00'</font>,<font color="#9933CC">'25.11.2003 11:00:00'</font>,<font color="#9933CC">'Test 2'</font>
      PRINT @iReturn
      -- Ergebnis prüfen
      <b>SELECT</b> * <b>FROM</b> Termin
      </pre&gt

      Comment


      • #4
        Trigger ok, aber wie kann ich einen Trigger so definieren. Und vorallem, kann ich über einen Trigger die Eingabe unterbinden

        Comment


        • #5
          Für den genaue Defintion des Trigger-Codes bei MS-SQL bei MS-SQL bin ich der Falsche. :-(<br>
          Meine Erfahrung damit sind die automatisch generierten Trigger eines ER-Tools

          Comment


          • #6
            Hallo,

            &gt;..kann ich über einen Trigger die Eingabe unterbinden ?

            selbstverständlich, indem auf <b>RAISERROR</b> zurückgegriffen wird. Das folgende Beispiel stammt aus der MS SQL Server-Hilfeseite für RAISERROR:
            <pre>
            CREATE TRIGGER employee_insupd
            ON employee
            FOR INSERT, UPDATE
            AS
            /* Get the range of level for this job type from the jobs table. */
            DECLARE @@MIN_LVL tinyint,
            @@MAX_LVL tinyint,
            @@EMP_LVL tinyint,
            @@JOB_ID smallint
            SELECT @@MIN_LVl = min_lvl,
            @@MAX_LV = max_lvl,
            @@ EMP_LVL = i.job_lvl,
            @@JOB_ID = i.job_id
            FROM employee e, jobs j, inserted i
            WHERE e.emp_id = i.emp_id AND i.job_id = j.job_id
            IF (@@JOB_ID = 1) and (@@EMP_lVl <> 10)
            BEGIN
            RAISERROR ('Job id 1 expects the default level of 10.', 16, 1)
            ROLLBACK TRANSACTION
            END
            ELSE
            IF NOT @@ EMP_LVL BETWEEN @@MIN_LVL AND @@MAX_LVL)
            BEGIN
            RAISERROR ('The level for job_id:%d should be between %d and %d.',
            16, 1, @@JOB_ID, @@MIN_LVL, @@MAX_LVL)
            ROLLBACK TRANSACTION
            END
            </pre&gt

            Comment

            Working...
            X