Funktion erstellen, Tabellenvariable zurückgeben T-SQL 2005



  • Hallo,

    ich habe folgende Funktion:

    ALTER FUNCTION dbo.func_be_bestand (@storeid int)
    RETURNS TABLE 
    AS
    DECLARE @tmp_lager_idents TABLE (LAGER_IDENT nvarchar(90))
    INSERT INTO @tmp_lager_idents SELECT LAGER_IDENT
    FROM OPENQUERY(ORANEXUS_SMTOFFICE, '
    			   SELECT LAGER_IDENT 
    			   FROM EW_BE_EINZELGEBINDE
    			   WHERE MENGE > 0
    			   GROUP BY LAGER_IDENT										  
    			   ')
    return
    (
      SELECT * FROM @tmp_lager_idents
    )
    

    Ich möchte die Ergebnistablle einfach nur zurückgeben lassen ohne die Tabellenstruktur vorher bei RETURNS zu erstellen, da diese nämlich später dynamisch werden soll.

    Folgende Fehlermeldungen gibt mit der SQL 2005 Server aus:

    Meldung 156, Ebene 15, Status 1, Prozedur func_be_bestand, Zeile 5
    Falsche Syntax in der Nähe des 'DECLARE'-Schlüsselwortes.
    Meldung 178, Ebene 15, Status 1, Prozedur func_be_bestand, Zeile 15
    Eine RETURN-Anweisung mit einem Rückgabewert kann in diesem Kontext nicht verwendet werden.

    Ich probiere schon sehr lange rum, und komme einfach nicht drauf was ich hier falsch mache... Vielleicht könnte mir wer helfen?

    Gruß Gustl



  • Bist du dir sicher dass das überhaupt geht? Ich glaube nämlich eher dass es nicht geht.
    Bzw. ich bin mir sogar fast sicher dass es nicht geht.

    Table-valued functions kann man ja in Abfragen verwenden, d.h. joinen und was nicht noch alles. Theoretisch wäre es zwar möglich zu erlauben dass die Struktur von den Parametern abhängt, aber es hätte einfach zu viele Nachteile.



  • Hallo hustbear,

    als Tabelle möchte ich eine dynamisch erstellte pivot-table zurückgeben.
    Diese soll aber vom Benutzer wie eine "normale" Tabelle behandelt werden können.

    Procedure fällt weg, da ich aus exec(proc) keine Abfrage machen kann.
    View geht glaub ich auch nicht...
    Was bleibt ist denke ich eine Funktion, die eine Tabelle zurückgibt.
    Mit der Inline-Tabellenwertfunktion kann ich eine Tabelle zurückgeben wo ich nicht den Rumpf mit angeben muss, somit dynamisch sein kann.
    Aber ich kann mit der Inline keine Zwischenschritte machen...

    Mit der Multistatement Tabellenwertfunktion kann ich zwar Berechnungen und Zwischenschritte machen, aber da muss ich den Rumpf der Tabelle mit angeben, welche ich zurückgeben will. Aber da mein pivot-Query und somit auch die Tabelle dynamisch aufgebaut wird, fällt dies auch weg.

    Hier wird das Statement generiert, welches ich zurückgeben möchte:

    DECLARE @PivotColumnHeaders VARCHAR(MAX)
    SELECT @PivotColumnHeaders = 
      COALESCE(
        @PivotColumnHeaders + ',[' + cast(LAGER_IDENT as varchar) + ']',
        '[' + cast(LAGER_IDENT as varchar)+ ']'
      )
    FROM (SELECT LAGER_IDENT
    	FROM OPENQUERY(ORANEXUS_SMTOFFICE, '
    				   SELECT LAGER_IDENT 
    				   FROM EW_BE_EINZELGEBINDE
    				   WHERE MENGE > 0
    				   GROUP BY LAGER_IDENT										  
    				   ORDER BY LAGER_IDENT')) p
    
    --SELECT @PivotColumnHeaders
    
    DECLARE @PivotTableSQL NVARCHAR(MAX)
    SET @PivotTableSQL = N'
    SELECT *
    FROM
    (SELECT     BE_IDENT, CAST(MENGE AS int) AS MENGE, LAGER_IDENT
    FROM         OPENQUERY(ORANEXUS_SMTOFFICE, ''
    SELECT BE_IDENT, COUNT(BE_IDENT) AS ANZAHL_GEBINDE, SUM(MENGE) AS MENGE, LAGER_IDENT 
    FROM EW_BE_EINZELGEBINDE
    WHERE MENGE > 0
    GROUP BY BE_IDENT, LAGER_IDENT										  
    '')) p
    PIVOT 
    (
    SUM(MENGE)
    FOR LAGER_IDENT IN
       (' + @PivotColumnHeaders + ')
     ) PivotTable
    ORDER BY BE_IDENT
    '
    --SELECT @PivotTableSQL
    
    EXECUTE(@PivotTableSQL)
    

    Hat wer eine Idee?
    Danke
    Gruß Gustl



  • Mit der Inline-Tabellenwertfunktion kann ich eine Tabelle zurückgeben wo ich nicht den Rumpf mit angeben muss, somit dynamisch sein kann.

    Hö?
    Die "Inline-Tabellenwertfunktion" ist einfach ein SELECT. Und ein direktes SELECT ist max. so "dynamisch" wie die Tabellen die es referenziert.
    Aber darum geht's nichtmal.

    Inline- und nicht-inline Table-Valued-Functions sind zwei ganz unterschiedliche Biester. Das eine (inline) ist nicht viel mehr als Textverarbeitung (wie z.B. auch eine View, so lange man nicht NOEXPAND verwendet). Bei "inline" wird die Information wie die resultierende Tabelle aussieht daher einfach aus dem SELECT Statement bezogen. Wie es eben auch laufen würde wenn man den Funktionsaufruf einfach mit dem Inhalt der Table-Valued-Function ersetzen würde.

    Nicht-inline Table-Valued-Functions sind da ganz andere Biester, weswegen sie SQL Server auch ganz anders behandelt (anders behandeln muss). Den Aufruf einer nicht-inline Table-Valued-Function kannst du auch nicht einfach durch den Code der Funktion ersetzen. Dazu müsste man erstmal ne Table-Variable anlegen, den Code der Table-Valued-Function so anpassen dass das letzte SELECT da rein INSERTed, und dort wo ursprünglich die Funktion aufgerufen wurde dann ein SELECT auf die Table-Variable machen.
    Und jetzt sollte auch klar werden wieso SQL Server hier wissen will wie die Tabelle aussieht.
    Die Info braucht er um den Execution-Plan aufzubauen.


Anmelden zum Antworten