1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  2. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Abfrabe möglich?

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von ClassMP, 15 September 2010.

  1. ClassMP

    ClassMP Benutzer

    Hi,

    ich möchte alle Artikel nach der ArtikelNummer gruppieren und soviel Datensätze zurückbekommen, wie es ArtikelVariantenDetails gibt.
    Dabei kann es sein, dass es den selben Artikel für mehrere Mandanten gibt.
    Diesen möchte ich aber nur von einem Mandanten in der Abfrage haben.

    Das Ergebnis sollte sein:
    ArtikelNummer ArtikelDetailId
    A5000 1
    A5000 2
    A5000 3


    Wie könnte die Abfrage aussehen?

    Tabellenstruktur:

    Tabelle: Artikel
    -----------------
    ArtikelId
    MandantId

    Tabelle: ArtikelVarianten
    ----------------------------
    ArtikelVariantenId
    ArtikelId
    ArtikelNummer

    Tabelle: ArtikelVariantenDetails
    ------------------------------------
    ArtikelVariantenDetailsId
    ArtikelVariantenId
    ArtikelDetailId


    Beispieldatensatz 1:

    Artikel:
    ---------
    MandantId: 1
    ArtikelId: 4711


    ArtikelVariante:
    ------------------
    ArtikelVariantenId: 1
    ArtikelId: 4711
    ArtikelNummer: A5000


    ArtikelVariantenDetails
    --------------------------
    ArtikelVariantenDetailId: 1
    ArtikelVariantenId: 1
    ArtikelDetailId: 1

    ArtikelVariantenDetailId: 2
    ArtikelVariantenId: 1
    ArtikelDetailId: 2

    ArtikelVariantenDetailId: 3
    ArtikelVariantenId: 1
    ArtikelDetailId: 3



    Beispieldatensatz 2:

    Artikel:
    ---------
    MandantId: 2
    ArtikelId: 4712


    ArtikelVariante:
    ------------------
    ArtikelVariantenId: 2
    ArtikelId: 4712
    ArtikelNummer: A5000


    ArtikelVariantenDetails
    --------------------------
    ArtikelVariantenDetailId: 3
    ArtikelVariantenId: 2
    ArtikelDetailId: 1

    ArtikelVariantenDetailId: 4
    ArtikelVariantenId: 2
    ArtikelDetailId: 2

    ArtikelVariantenDetailId: 5
    ArtikelVariantenId: 2
    ArtikelDetailId: 3
     
  2. thomas_w

    thomas_w Datenbank-Guru

    AW: Abfrabe möglich?

    Die Abfrage sollte ungefähr so aussehen (wenn ich mich nicht vertippt habe..):

    Code:
    SELECT a.artikelnummer, avd.artikeldetailid
      FROM artikel a
      JOIN artikelvarianten av
        ON av.artikelid = a.artikelid
      JOIN artikelvariantendetails avd
        ON avd.artikelvariantenid = av.artikelvariantenid
    ORDER BY a.artikelnummer;
    
    Grüße
    Thomas
     
  3. ClassMP

    ClassMP Benutzer

    AW: Abfrabe möglich?

    Hallo Thomas,

    danke für deine Antwort.
    Leider werden mit deiner Abfrage dann alle Artikel mit der selben Artikelnummer angezeigt, da es den Artikel mit der selben Artikelnummer bei zwei Mandanten gibt.

    Das Ziel ist es den Artikel nur einmal, mit allen Details, im Result zu bekommen.

    Hast du evtl. noch einen Ansatz?
     
  4. thomas_w

    thomas_w Datenbank-Guru

    AW: Abfrabe möglich?

    Dann schränken wir die Abfrage noch auf den Mandanten ein. Also z. B auf den Mandanten 1:

    Code:
    SELECT a.artikelnummer, avd.artikeldetailid
      FROM artikel a
      JOIN artikelvarianten av
        ON av.artikelid = a.artikelid
      JOIN artikelvariantendetails avd
        ON avd.artikelvariantenid = av.artikelvariantenid
     WHERE a.MandantId = 1
    ORDER BY a.artikelnummer;
    
    Grüße
    Thomas
     
  5. ClassMP

    ClassMP Benutzer

    AW: Abfrabe möglich?

    Hallo Thomas,

    danke das klappt soweit.

    Nun habe ich aber noch eine andere Abfrage die unabhängig vom Mandanten ist.
    Sie soll mir alle Artikel zusammenfassen, in denen alle ArtikelDetailIds in der Tabelle ArtikelVariantenDetails und die ArtikelNummer aus der Tabelle ArtikelVarianten gleich sind.

    Das Result wäre dann für das Beispiel

    ArtikelNummer
    A5000
     
  6. thomas_w

    thomas_w Datenbank-Guru

    AW: Abfrabe möglich?

    Könnte so gehen, (wenn ich keinen Tippfehler drin habe)

    Code:
    SELECT DISTICT av.artikelnummer
      FROM artikel a
      JOIN artikelvarianten av
        ON av.artikelid = a.artikelid
      JOIN artikelvariantendetails avd
        ON avd.ArtikelDetailId = av.artikelnummer
    ORDER BY av.artikelnummer
    
    Grüße
    Thomas
     
  7. ClassMP

    ClassMP Benutzer

    AW: Abfrabe möglich?

    Sorry mein Schuld, es ist etwas komplexer wie ich jetzt festgestellt habe!
    Dafür muss ich noch ein wenig mehr ausholen.
    Die Daten werden in C# Objekten gespeichert und in einer Anwendung angezeigt.

    Ziel ist nach Artikeln mandantenübergreifend zu suchen.
    Filterkriterien sind der ProduktTyp (ProduktTypId aus ProduktTypen) und die ProduktDetails (ProduktDetailId aus ProduktDetails), die dem ProduktTyp
    in ProductDetailZuordnungen zugeordnet sind.

    Hier das Szenario in der Anwendung:

    1. Ansicht:
    Es sollten alle Artikel, gruppiert nach der ArtikelNummer und mit allen ProductDetails aufgelöst in einem Datensatz, anzeigt werden.

    2. Ansicht:
    Nach der Auswahl eines (gruppierten) Artikels in der 1. Ansicht sollten alle Mandanten erscheinen, die den o.g. Artikel angelegt haben.

    3. Ansicht:
    Wenn nun ein Mandant ausgewählt wird, sollen die kompletten Daten des Artikels (vom jeweiligen Mandanten) angezeigt werden.

    Wie könnten die SQL Statements dafür aussehen?


    Die Tabellenstruktur sieht wie folgt aus:

    Tabellenstruktur:

    Tabelle: Artikel
    --------------
    ArtikelId
    MandantId
    ArtikelTypId


    Tabelle: ArtikelTypen
    --------------------
    ArtikelTypId
    Bezeichnung


    Tabelle: ArtikelDetailGruppen
    ----------------------------
    ArtikelDetailGruppeId
    Bezeichnung


    Tabelle: ArtikelDetails
    ---------------------
    ArtikelDetailId
    ArtikelDetailGruppeId
    Bezeichnung


    Tabelle: ArtikelDetailZuordnungen
    --------------------------------
    ArtikelDetailZuordnungId
    ArtikelTypId
    ArtikelDetailGruppeId


    Tabelle: ArtikelVarianten
    ----------------------------
    ArtikelVariantenId
    ArtikelId
    ArtikelNummer


    Tabelle: ArtikelVariantenDetails
    ------------------------------------
    ArtikelVariantenDetailsId
    ArtikelVariantenId
    ArtikelDetailId


    Beispieldatensatz:

    ArtikelTyp:
    ---------
    ArtikelTypId: 1
    Bezeichnung: Schaltkasten


    ArtikelDetailGruppen:
    -------------------
    ArtikelDetailGruppeId: 1
    Bezeichnung: Schrauben

    ArtikelDetailGruppeId: 2
    Bezeichnung: Muttern


    ArtikelDetails:
    -------------
    ArtikelDetailId: 1
    ArtikelGruppeId: 1
    Bezeichnung: M5 25mm

    ArtikelDetailId: 2
    ArtikelGruppeId: 2
    Bezeichnung: M5

    ArtikelDetailId: 3
    ArtikelGruppeId: 1
    Bezeichnung: M6 50mm

    ArtikelDetailId: 4
    ArtikelGruppeId: 2
    Bezeichnung: M6


    ArtikelDetailZuordnungen:
    ------------------------
    ArtikelDetailZuordnungId: 1
    ArtikelTypId: 1
    ArtikelDetailGruppeId: 1

    ArtikelDetailZuordnungId: 1
    ArtikelTypId: 1
    ArtikelDetailGruppeId: 2


    Artikel:
    ---------
    MandantId: 1
    ArtikelId: 4711
    ArtikelTypId: 1

    MandantId: 2
    ArtikelId: 4712
    ArtikelTypId: 1

    MandantId: 1
    ArtikelId: 4713
    ArtikelTypId: 1


    ArtikelVariante:
    ------------------
    ArtikelVariantenId: 1
    ArtikelId: 4711
    ArtikelNummer: A5000

    ArtikelVariantenId: 2
    ArtikelId: 4712
    ArtikelNummer: A5000

    ArtikelVariantenId: 3
    ArtikelId: 4713
    ArtikelNummer: A5001


    ArtikelVariantenDetails
    --------------------------
    ArtikelVariantenDetailId: 1
    ArtikelVariantenId: 1
    ArtikelDetailId: 1

    ArtikelVariantenDetailId: 2
    ArtikelVariantenId: 1
    ArtikelDetailId: 2

    ArtikelVariantenDetailId: 3
    ArtikelVariantenId: 2
    ArtikelDetailId: 1

    ArtikelVariantenDetailId: 4
    ArtikelVariantenId: 2
    ArtikelDetailId: 2

    ArtikelVariantenDetailId: 5
    ArtikelVariantenId: 3
    ArtikelDetailId: 3

    ArtikelVariantenDetailId: 6
    ArtikelVariantenId: 3
    ArtikelDetailId: 4
     
  8. thomas_w

    thomas_w Datenbank-Guru

    AW: Abfrabe möglich?

    Ich glaube, das sprengt jetzt etwas den Rahmen eines freiwilligen Forums. Damit wir Dir helfen können, musst Du wenigsten die Daten so aufbereiten, dass wir diese direkt verwenden können. Also bitte das Ganze in

    1. CREATE TABLE Strukturen umbauen
    2. Passende INSERT Befehle erzeugen
    3. Ein paar eigene Überlegungen zu den SQL-Abfragen beisteuern
    Grüße
    Thomas
     
  9. ClassMP

    ClassMP Benutzer

    AW: Abfrabe möglich?

    Ja sorry ich war gerade so dabei das Szeario zu durchdenken, daß ich alles andere vergessen habe. Werde jetzt soweit alles vorbereiten und ein paar Tests machen...
     
  10. ClassMP

    ClassMP Benutzer

    AW: Abfrabe möglich?

    Hi hier nochmal das fehlende Skript

    Code:
     
    /****************
     * ArtikelTypen *
     ***************/
    CREATE TABLE [dbo].[ArtikelTypen]
    (
     [ArtikelTypId] [int] NOT NULL,
     [Bezeichnung] [varchar](50) NOT NULL
    ) 
    ON [PRIMARY]
     
    INSERT INTO ArtikelTypen
    (ArtikelTypId, Bezeichnung)
    VALUES
    (1, 'Schaltkasten')
     
    /************************
     * ArtikelDetailGruppen *
     ***********************/
    CREATE TABLE [dbo].[ArtikelDetailGruppen]
    (
     [ArtikelDetailGruppeId] [int] NOT NULL,
     [Bezeichnung] [varchar](50) NOT NULL
    ) 
    ON [PRIMARY]
     
    INSERT INTO ArtikelDetailGruppen
    (ArtikelDetailGruppeId, Bezeichnung)
    VALUES
    (1, 'Schraube')
     
    INSERT INTO ArtikelDetailGruppen
    (ArtikelDetailGruppeId, Bezeichnung)
    VALUES
    (2, 'Mutter')
     
    /******************
     * ArtikelDetails *
     *****************/
    CREATE TABLE [dbo].[ArtikelDetails]
    (
     [ArtikelDetailId] [int] NOT NULL,
     [ArtikelDetailGruppeId] [int] NOT NULL,
     [Bezeichnung] [varchar](50) NOT NULL
    ) 
    ON [PRIMARY]
     
    INSERT INTO ArtikelDetails
    (ArtikelDetailId, ArtikelDetailGruppeId, Bezeichnung)
    VALUES
    (1, 1, 'M5 25mm')
     
    INSERT INTO ArtikelDetails
    (ArtikelDetailId, ArtikelDetailGruppeId, Bezeichnung)
    VALUES
    (2, 1, 'M5 50mm')
     
    INSERT INTO ArtikelDetails
    (ArtikelDetailId, ArtikelDetailGruppeId, Bezeichnung)
    VALUES
    (3, 1, 'M6 50mm')
     
    INSERT INTO ArtikelDetails
    (ArtikelDetailId, ArtikelDetailGruppeId, Bezeichnung)
    VALUES
    (4, 2, 'M5')
     
    INSERT INTO ArtikelDetails
    (ArtikelDetailId, ArtikelDetailGruppeId, Bezeichnung)
    VALUES
    (5, 2, 'M6')
     
    /****************************
     * ArtikelDetailZuordnungen *
     ***************************/
    CREATE TABLE [dbo].[ArtikelDetailZuordnungen]
    (
     [ArtikelDetailZuordnungId] [int] NOT NULL,
     [ArtikelTypId] [int] NOT NULL,
     [ArtikelDetailGruppeId] [int] NOT NULL
    ) 
    ON [PRIMARY]
     
    INSERT INTO ArtikelDetailZuordnungen
    (ArtikelDetailZuordnungId, ArtikelTypId, ArtikelDetailGruppeId)
    VALUES
    (1, 1, 1)
     
    INSERT INTO ArtikelDetailZuordnungen
    (ArtikelDetailZuordnungId, ArtikelTypId, ArtikelDetailGruppeId)
    VALUES
    (1, 1, 2)
     
    /***********
     * Artikel *
     **********/
    CREATE TABLE [dbo].[Artikel]
    (
     [ArtikelId] [int] NOT NULL,
     [MandantId] [int] NOT NULL,
     [ArtikelTypId] [int] NOT NULL,
     [Bezeichnung] [varchar](50) NOT NULL
    ) 
    
    ON [PRIMARY] 
    INSERT INTO Artikel
    (ArtikelId, MandantId, ArtikelTypId, Bezeichnung)
    VALUES
    (1, 1, 1, 'Schaltkasten groß')
     
    INSERT INTO Artikel
    (ArtikelId, MandantId, ArtikelTypId, Bezeichnung)
    VALUES
    (2, 2, 1, 'Schaltkasten groß')
     
    INSERT INTO Artikel
    (ArtikelId, MandantId, ArtikelTypId, Bezeichnung)
    VALUES
    (3, 1, 1, 'Schaltkasten mittel')
     
    /********************
     * ArtikelVarianten *
     ********************/
    CREATE TABLE [dbo].[ArtikelVarianten]
    (
     [ArtikelVarianteId] [int] NOT NULL,
     [ArtikelId] [int] NOT NULL,
     [ArtikelNummer] [varchar](50) NOT NULL
    ) 
    ON [PRIMARY] 
     
    INSERT INTO ArtikelVarianten
    (ArtikelVarianteId, ArtikelId, ArtikelNummer)
    VALUES
    (1, 1, '4711')
     
    INSERT INTO ArtikelVarianten
    (ArtikelVarianteId, ArtikelId, ArtikelNummer)
    VALUES
    (2, 2, '4711')
     
    INSERT INTO ArtikelVarianten
    (ArtikelVarianteId, ArtikelId, ArtikelNummer)
    VALUES
    (3, 3, '4712')
    
    /***************************
     * ArtikelVariantenDetails *
     **************************/
    CREATE TABLE [dbo].[ArtikelVariantenDetails]
    (
     [ArtikelVariantenDetailId] [int] NOT NULL,
     [ArtikelVariantenId] [int] NOT NULL,
     [ArtikelDetailId] [int] NOT NULL
    ) 
    ON [PRIMARY]
     
    INSERT INTO ArtikelVariantenDetails
    (ArtikelVariantenDetailId, ArtikelVariantenId, ArtikelDetailId)
    VALUES
    (1, 1, 1)
     
    INSERT INTO ArtikelVariantenDetails
    (ArtikelVariantenDetailId, ArtikelVariantenId, ArtikelDetailId)
    VALUES
    (2, 1, 4)
     
    INSERT INTO ArtikelVariantenDetails
    (ArtikelVariantenDetailId, ArtikelVariantenId, ArtikelDetailId)
    VALUES
    (3, 2, 1)
     
    INSERT INTO ArtikelVariantenDetails
    (ArtikelVariantenDetailId, ArtikelVariantenId, ArtikelDetailId)
    VALUES
    (4, 2, 4)
     
    INSERT INTO ArtikelVariantenDetails
    (ArtikelVariantenDetailId, ArtikelVariantenId, ArtikelDetailId)
    VALUES
    (5, 3, 2)
     
    INSERT INTO ArtikelVariantenDetails
    (ArtikelVariantenDetailId, ArtikelVariantenId, ArtikelDetailId)
    VALUES
    (6, 3, 4)
    
    
     
  11. Charly

    Charly Datenbank-Guru

    AW: Abfrabe möglich?

    Hallo,

    das würde ich nicht mit SQL-Statements lösen. Das schreit nach Funktionen.

    zu 1. Alles Gut bis auf alle Details aus Tabelle ArtikelDetails in einer Zeile.
    Hier braucht man meiner Meinung nach eine Funktion
    zu 2. Ansicht
    Code:
    SELECT MandantID FROM Artikel WHERE ArtikeID = @ArtikelID
    in eine Inline-Funktion gepack.

    zu 3. wieder mit allen Details aus Tabelle ArtikelDetails?
    Dann auch wieder eine Funktion.

    Warum Funktionen? Wenn ein Artikel immer gleich viele Details hat kann mann die Tabelle mit JOINS zusammenbauen. Wird tierisch langsam.
    Ich gehe mal davon aus das nicht immer die gleiche Anzahl von ArtikelDetails vorhanden sind. Deshalb eine Funktion die dynamisch Detail-Spalten hinzufügt.

    Ich schau mal was sich da machen lässt. Kann aber ein bisschen dauern.

    Wenn ich was falsch verstanden habe bitte melden.:)


    Gruß Charly
     
  12. ClassMP

    ClassMP Benutzer

    AW: Abfrabe möglich?

    Hallo Charly,

    danke das wäre super.
    Soweit hast du alles gut verstanden ;)
     
  13. Charly

    Charly Datenbank-Guru

    AW: Abfrabe möglich?

    Hallo,

    wie gesagt es hat ein bisschen gedauert aber sowas schüttelt man nicht eben mal so aus dem Ärmel.

    Warum soviel Mühe? Das Problem Daten im SQL-Server um 90 Grad zu drehen kommt bestimmt öffter vor. Und wenn es hier nicht um z.B. Verkaufszahlen geht, kann man auch nicht mit solchen Konstrukten wie ROLLUP oder CUBE arbeiten.

    Ich muss etwas ausholen um die Funktionsweise zu erklären:

    Es werden 2 Temporäre Tabellen, ein Cursor und diverse Variablen erzeugt.

    Cursor sind eigentlich nicht so gerne bei den Profis gesehen. Es macht die Sache aber erheblich übersichtlicher.

    Die Tabelle #Input benutze ich um die Maximale anzahl von Detaildatensätzen zu finden. Dann wird sie wieder gelöscht.
    Mir ist nichts besseres eingefallen.:(

    Tabelle Output ist der Rückgabewert der Prozedur. Hier wird ne ganz Menge mit angestellt. Zuerst wird mit der Create nur der 'Rumpf' erzeugt.

    Dann mit Hilfe der aus der #Input Tabelle ermittelten Anzahl der Details-Datensätze Spalten hinzugefügt. Das erledige ich mit sp_executesql dem man einfach einen zusammengebauten SQL-String übergeben kann.

    In unserem Fall ein ALTER TABLE Statement

    Danach wird mit Hilfe einer verschachtelten WHILE durch die Datensätze gelaufen bis ale Artikel Ihre Details in den Spalten haben. Die Möglichkeit das keine Details existieren wurde nicht getestet.

    Das INSERT erzeugt die neuen Datensätze und mit sp_executesql werden die Detailspalten befüllt.

    So jetzt erstmal die Prozedur:
    Code:
    IF EXISTS (SELECT name FROM sysobjects WHERE name = N'Artikel_und_Details' AND type = 'P')
        DROP PROCEDURE Artikel_und_Details
    GO
    CREATE PROC Artikel_und_Details
    AS
    CREATE TABLE #INPUT (ArtikelId int, ArtikelDetailId int)
    -- Grundgerüst für die #Output Tabelle
    CREATE TABLE #OUTPUT (IDX int)
    -- Cursor erzeugen um durch die Tabelle zu laufen
    DECLARE Artikel_Cursor CURSOR
     FOR 
      SELECT A.ArtikelId, AD.ArtikelDetailId
      FROM Artikel AS A
      JOIN ArtikelVarianten AS AV ON A.ArtikelID = AV.ArtikelID
      JOIN ArtikelTypen AS ATY ON A.ArtikelTypID = ATY.ArtikelTypID
      JOIN ArtikelDetailZuordnungen AS ADZ ON ATY.ArtikelTypID=ADZ.ArtikelTypID 
      JOIN ArtikelDetailGruppen AS ADG ON ADG.ArtikelDetailGruppeId=ADZ.ArtikelDetailGruppeId
      JOIN ArtikelDetails AS AD ON AD.ArtikelDetailID=ADZ.ArtikelDetailGruppeID
      ORDER BY A.ArtikelId
    DECLARE @Detail_Columns int, -- Anzahl der Detail-Spalten
       @Counter int, -- allgemeiner Zähler
       @Artikel_Columns int, -- Anzahl der Artikel-Spalten
       @StrSQL nvarchar(4000), -- Zum zusammenbauen von SQL-Statements
       @ArtikelID int,
       @Artikel_Counter int, -- zum vergleichen mit einem Zähler
       @ArtikelDetailID int
    SET  @Counter = 1
    SET  @Artikel_Columns = 1 -- Setzen der Artikel_Spalten-Anzahl
    -- Temporäre Tabelle um die Anzahl der Detail-Spalten zu bekommen
    INSERT INTO #INPUT
      SELECT DISTINCT A.ArtikelId, AD.ArtikelDetailId
      FROM Artikel AS A
      JOIN ArtikelVarianten AS AV ON A.ArtikelID = AV.ArtikelID
      JOIN ArtikelTypen AS ATY ON A.ArtikelTypID = ATY.ArtikelTypID
      JOIN ArtikelDetailZuordnungen AS ADZ ON ATY.ArtikelTypID=ADZ.ArtikelTypID 
      JOIN ArtikelDetailGruppen AS ADG ON ADG.ArtikelDetailGruppeId=ADZ.ArtikelDetailGruppeId
      JOIN ArtikelDetails AS AD ON AD.ArtikelDetailID=ADZ.ArtikelDetailGruppeID
      ORDER BY A.ArtikelId
     
    SELECT @Detail_Columns = COUNT(ArtikelDetailId) FROM #INPUT GROUP BY ArtikelID
    -- Hier werden die Spalten für die Detail Datensätze angelegt
    WHILE @Counter <= @Detail_Columns
     BEGIN
      SET @StrSQL = 'ALTER TABLE #OUTPUT ADD DETAIL' + CAST(@Counter AS nvarchar) + ' int;'
      EXEC sp_executesql @StrSQL 
      SET @Counter = @Counter + 1
     END
    DROP TABLE #INPUT -- So, die brauchen wir jetzt nicht mehr
    SET @Counter = 1
    OPEN Artikel_Cursor
    FETCH NEXT FROM Artikel_Cursor INTO @ArtikelID, @ArtikelDetailID
    WHILE @@FETCH_STATUS = 0
     BEGIN -- Alle Artikel durchlaufen
       SET @Counter = 1 -- Detailzähler zurücksetzen 
       SET @Artikel_Counter = @ArtikelID -- Aktuelle ArtikelId merken
       INSERT INTO #OUTPUT (IDX) VALUES (@ArtikelID)
        WHILE @Artikel_Counter = @ArtikelID AND  @@FETCH_STATUS = 0 --Details für jeden Artikel durchlaufen
         BEGIN 
          SET @StrSQL = 'UPDATE #OUTPUT SET DETAIL' + CAST(@Counter AS nvarchar) + ' = ' 
          + CAST(@ArtikelDetailID AS nvarchar) + ' WHERE IDX = ' + CAST(@ArtikelID AS nvarchar) + ';'
          EXEC sp_executesql @StrSQL
          SET @Counter = @Counter + 1
          FETCH NEXT FROM Artikel_Cursor INTO @ArtikelID, @ArtikelDetailID
     
         END
     END
    CLOSE Artikel_Cursor
    DEALLOCATE Artikel_Cursor
    SELECT * FROM #OUTPUT
    RETURN 0
    DROP TABLE #OUTPUT
    GO
    
    Ausführen kann man das dann mit:

    Code:
    EXEC Artikel_und_Details
    Das spuckt ja nur Zahlen aus!

    OK, zum anpassen der Prozedur gibt es folgendes zu sagen:

    Die Abfrage die den Cursor erzeugt hat zurzeit nur 2 Ergebnisspalten.

    Wenn man mehr Infos in der Ausgabetabelle haben möchte muus man erstmal hier die gewünschten Spalten aus der Artikeltabelle und der Detail Tabelle eintragen.

    Das hat noch ein paar andere änderungen zu Folge:

    1. die Anzahl der Artikel_Columns muss angepasst werden.
    2. Die Create-Anweiseung für die Tabelle #OUTPUT muss angepasst werden.
    3. Die Insert Anweisung in der äuseren WHILE muss angepasst werden
    4. Weitere Variablen Wie die @Artikeldetails für die INSERT Anweisung müssen erzeugt werden
    5. Die Anweisung zum erzeugen von Detalispalten muss erweitert werden. Auch einfach durch kopieren und anpassen der beiden Zeilen
    Code:
      SET @StrSQL = 'ALTER TABLE #OUTPUT ADD DETAIL' + CAST(@Counter AS nvarchar) + ' int;'
      EXEC sp_executesql @StrSQL 
    Daraus machen wir einfach
    Code:
      SET @StrSQL = 'ALTER TABLE #OUTPUT ADD Bezeichnung' + CAST(@Counter AS nvarchar) + ' nvarchar(50);'
      EXEC sp_executesql @StrSQL 
    6. Für weiter Spalten aus der Details Tabelle müssen zusätzlich Update-Anweisungen erzeugt werden. Diese beiden Zeilen einfach anpassen
    und untereinander Kopieren.
    Code:
          SET @StrSQL = 'UPDATE #OUTPUT SET DETAIL' + CAST(@Counter AS nvarchar) + ' = ' 
          + CAST(@ArtikelDetailID AS nvarchar) + ' WHERE IDX = ' + CAST(@ArtikelID AS nvarchar) + ';'
          EXEC sp_executesql @StrSQL
    7.Natürlich müssen die FETCH-Anweisung so erweitert werden das hinzugefügte Spalten in Variablen gespeichert werden die man dann mit den Anweisungen von Punkt 5 und 6 in die Output-Tabelle schreiben kann.

    So, ich hoffe das ich nichts vergessen habe.

    Jetzt noch die Mandanten zum Artikel abfragen:

    Code:
    IF EXISTS (SELECT * FROM sysobjects WHERE name = N'Mandanten_Artikel')
     DROP FUNCTION Mandanten_Artikel
    GO
    CREATE FUNCTION Mandanten_Artikel 
     (ArtikelID int)
    RETURNS TABLE 
    AS
     RETURN SELECT MandantID FROM Artikel WHERE ArtikeID = @ArtikelID
    GO
    
    Das kann man dann so abfragen:

    Code:
    SELECT * FROM Mandanten_Artikel (ArtikelID)
    GO
    Für Punkt 3 kann man einfach die SELECT aus der Prozedur für die 1 Abfrage nehmen und in eine Inline Funktion packen.

    Hier nur die 1er in der WHERE durch Variablen wie zu Punkt 2 ersetzen.

    Code:
    SELECT DISTINCT A.ArtikelId, AD.ArtikelDetailId
      FROM Artikel AS A
      JOIN ArtikelVarianten AS AV ON A.ArtikelID = AV.ArtikelID
      JOIN ArtikelTypen AS ATY ON A.ArtikelTypID = ATY.ArtikelTypID
      JOIN ArtikelDetailZuordnungen AS ADZ ON ATY.ArtikelTypID=ADZ.ArtikelTypID 
      JOIN ArtikelDetailGruppen AS ADG ON ADG.ArtikelDetailGruppeId=ADZ.ArtikelDetailGruppeId
      JOIN ArtikelDetails AS AD ON AD.ArtikelDetailID=ADZ.ArtikelDetailGruppeID
      WHERE A.MandantID = 1 AND A.ArtikelID = 1
    Ich hoffe das Du mit den Prozeduren und Funktionen zurecht kommts und das sich nicht so viele Fehler in dei Prozeduren eigeschlichen haben. Ich braucht man bestimmt noch eine menge sogenannter end-to-end Tests um alle eventualitäten abzufangen. Es ist auch keine richtige Fehlerbehandlung implementiert. Ich wollte ja auch nur den groben Weg vorgeben.

    Mit den Testdaten hat alles wie gewünscht funktioniert.

    Gruß Charly

    PS: Ich habs versprochen also habe ich es auch gemacht.:)
     
  14. ClassMP

    ClassMP Benutzer

    AW: Abfrabe möglich?

    Hi Charly,

    danke für deine Antwort.
    Bin gerade erst aus dem Urlaub zurück, deswegen die verspätete Reaktion.

    Ich werde deine Lösung mal umsetzen und ein paar Tests durchführen.
    Damach gebe ich nochmal ein Feedback...

    Gruß
    Marco
     
Die Seite wird geladen...

Diese Seite empfehlen