Hannes: Problem mit Pivot-Script in SQL

Hallo Forum!

Ich habe auf der Seite
http://www.itrain.de/knowhow/sql/tsql/pivot/sp_transform_v1_1.asp
ein Script gefunden, um mit SQL Server eine Pivot-Tabelle zu erzeugen.
Obwohl meine SQL-Kenntnisse ziemlich dünn sind, habe ich es auch geschafft, das Script um 2 Parameter zu erweitern (schart, termin), die dann als Bedingungen in der Query mit eingebaut werden.
Jetzt benötige ich noch einen weiteren, dritten Parameter (lamt). Und an dem scheitere ich. Liegt wohl daran, dass die ersten zwei vom Datentyp int waren und der dritte nun ein varchar ist. Ich glaube, es liegt bloß an den Anführungszeichen, dass das ganze nicht funktioniert. Aber ich komme nicht dahinter, wie es richtig heißen muss.

Vielleicht sieht jemand von euch den Fehler und kann mir helfen.
Das Ausgangsscript seht ihr auf der oben genannten Seite.

Ich habe es folgendermaßen angepasst:

  @Aggregate_Function nvarchar(30) = 'SUM',  
  @Aggregate_Column   nvarchar(255),  
  @TableOrView_Name   nvarchar(255),  
  @Select_Column     nvarchar(255),  
  @Pivot_Column       nvarchar(255),  
  @schart     int,  
  @termin       int,  
  @lamt      nvarchar(5),  
  @DEBUG      bit = 1  
 AS  
 SET NOCOUNT ON  
 DECLARE @TransformPart   nvarchar(4000)  
 DECLARE @SQLColRetrieval nvarchar(4000)  
 DECLARE @SQLSelectIntro  nvarchar(4000)  
 DECLARE @SQLSelectFinal  nvarchar(4000)  
  
 IF @Aggregate_Function NOT IN ('SUM', 'COUNT', 'MAX', 'MIN', 'AVG', 'STDEV', 'VAR', 'VARP', 'STDEVP')  
  BEGIN RAISERROR ('Invalid aggregate function: %s', 10, 1, @Aggregate_Function) END  
 ELSE  
 BEGIN  
  SELECT @SQLSelectIntro = 'SELECT CASE WHEN (GROUPING('  +  
          QUOTENAME(@Select_Column)       +  
     ') = 1) THEN ''Summe'' ELSE '   +  
     'CAST( + '                      +  
                                 QUOTENAME(@Select_Column)       +  
     ' AS NVARCHAR(255)) END As '    +  
     QUOTENAME(@Select_Column)       +  
     ', '  
  IF @DEBUG = 1 PRINT @sqlselectintro  
  SET @SQLColRetrieval =  
  N'SELECT @TransformPart = CASE WHEN @TransformPart IS NULL THEN ' +  
    N'''' + @Aggregate_Function + N'(CASE CAST(' +  
    QUOTENAME(CAST(@Pivot_Column AS VARCHAR(255))) +  
    N' AS VARCHAR(255)) WHEN '''''' + CAST('  +  
    QUOTENAME(@Pivot_Column) +  
    N' AS NVarchar(255)) + '''''' THEN ' + @Aggregate_Column +  
    N' ELSE null END) AS '' + QUOTENAME(' +  
    QUOTENAME(CAST(@Pivot_Column AS VARCHAR(255))) +  
    N') ELSE  @TransformPart + '', ' + @Aggregate_Function +  
    N' (CASE CAST(' + QUOTENAME(@Pivot_Column) +  
    N' AS nVARCHAR(255)) WHEN '''''' + CAST(' +  
    QUOTENAME(CAST(@Pivot_Column As VarChar(255))) +  
    N' AS nVARCHAR(255)) + '''''' THEN ' +  
    @Aggregate_Column +  
    N' ELSE null END) AS '' + QUOTENAME(' +  
    QUOTENAME(CAST(@Pivot_Column AS VARCHAR(255))) +  
    N') END FROM (SELECT DISTINCT ' +  
    QUOTENAME(CAST(@Pivot_Column AS VARCHAR(255))) +  
    N' FROM ' + @TableOrView_Name +  
    ' WHERE schart=' + CAST(@schart AS VARCHAR(255)) + ' and lamt='''+ @lamt + ''' and termin=' + CAST(@termin AS VARCHAR(255)) + ')  
    SelInner'  
  IF @DEBUG = 1 PRINT @SQLColRetrieval  
  EXEC sp_executesql @SQLColRetrieval,  
                            N'@TransformPart nvarchar(4000) OUTPUT',  
                            @TransformPart OUTPUT  
  IF @DEBUG = 1 PRINT @TransformPart  
  SET @SQLSelectFinal =  
                            N', ' + @Aggregate_Function + N'(' +  
                            CAST(@Aggregate_Column As Varchar(255)) +  
                            N') As Summe FROM ' + @TableOrView_Name  
                            + N' WHERE schart=' + CAST(@schart AS VARCHAR(2)) + ' and lamt=''' + @lamt +  ''' and termin=' + CAST(@termin AS VARCHAR(255))  
                            + ' GROUP BY ' +  @Select_Column + N' WITH CUBE'  
  IF @DEBUG = 1 PRINT @SQLSelectFinal  
  IF @DEBUG = 1 PRINT (@SQLSelectIntro + @TransformPart + @SQLSelectFinal)  
  EXEC (@SQLSelectIntro + @TransformPart + @SQLSelectFinal)  
  
 END

Aufruf:

exec se_sp_pivot 'COUNT','z2','se_v_pivot_bew_fach1Xz2','fachbe','z2',2, 1202, 'GY'

Fehler-Meldung:

Meldung 102, Ebene 15, Status 1, Zeile 1
Falsche Syntax in der Nähe von ','.
Meldung 319, Ebene 15, Status 1, Zeile 1
Falsche Syntax in der Nähe des WITH-Schlüsselworts. Falls diese Anweisung ein allgemeiner Tabellenausdruck, eine XMLNAMESPACES-Klausel oder eine CHANGE TRACKING CONTEXT-Klausel ist, muss die vorherige Anweisung mit einem Semikolon abgeschlossen werden.

Würde mich sehr freuen, wenn mir jemand auf die Sprünge helfen könnte!
Grüße, Hannes

  1. Hallo Hannes,

    http://www.itrain.de/knowhow/sql/tsql/pivot/sp_transform_v1_1.asp
    ein Script gefunden, um mit SQL Server eine Pivot-Tabelle zu erzeugen.

    seit MS SQL Server 2005 unterstützt Transact-SQL Kreuztabellenabfragen, siehe z.B. http://msdn.microsoft.com/de-de/library/ms177410(v=sql.90).aspx.

    Vermutlich ist daher der verwendete Ansatz obsolet.

    Freundliche Grüße

    Vinzenz

  2. Hallo,

    EXEC (@SQLSelectIntro + @TransformPart + @SQLSelectFinal)

    das wird wohl nicht so ganz gueltiges T-SQL ergeben, was sich im folgenden als

    Meldung 102, Ebene 15, Status 1, Zeile 1
    Falsche Syntax in der Nähe von ','.
    Meldung 319, Ebene 15, Status 1, Zeile 1
    Falsche Syntax in der Nähe des WITH-Schlüsselworts. Falls diese Anweisung ein allgemeiner Tabellenausdruck, eine XMLNAMESPACES-Klausel oder eine CHANGE TRACKING CONTEXT-Klausel ist, muss die vorherige Anweisung mit einem Semikolon abgeschlossen werden.

    aeussert.

    Vielleicht solltest du das Script im DEBUG modus aufrufen, dir die in diesem Fall erfolgenden Ausgaben (-> stichwort PRINT):

    IF @DEBUG = 1 PRINT @SQLSelectFinal
      IF @DEBUG = 1 PRINT (@SQLSelectIntro + @TransformPart + @SQLSelectFinal)

    1. anschauen
    2. per copy und paste in ein neues Abfragefenster packen und
    3. ausfuehren und den Fehler analysieren, der dann gemeldet wird
    4. diese ueberkandidelte Prozedur anpassen, dass sie gueltiges T-SQL erzeugt

    Ich habe es folgendermaßen angepasst:

    Ist im uebrigen schon mal der erste Grund warum es nicht mehr funzt :-)

    Cheers, Frank