Das Problem
Gespeicherte Prozeduren, die Dynamisches SQL und Temp-Tabellen enthalten, sind der Fluch von Zauberern wie SSRS und ORM-Generatoren wie Linq2SQL und EF Reverse Engineering-Tools.
Dies liegt daran, dass die Tools SET FMTONLY ON;
(oder neuerdings sp_describe_first_result_set
) vor dem Ausführen der PROC ausführen, um das von der PROC erzeugte Ergebnisset-Schema abzuleiten, damit Zuordnungen für die ReportViewer-Benutzeroberfläche generiert werden können. Weder FMTONLY ON
noch sp_describe_first_result
führen die PROC tatsächlich aus.
Zum Beispiel macht das Tool etwas wie:
SET FMTONLY ON;
EXEC dbo.MyProc NULL;
Einige Workarounds:
- Manuelles Bearbeiten der RDL / RDLC-Datei, um die tatsächlichen Spaltennamen und -typen des Ergebnissets einzufügen.
- Vorübergehend die echte Prozedur fallen lassen und sie durch eine ersetzen, die einen Datensatz von null oder mehr Zeilen mit den tatsächlichen Datentypen und Spaltennamen zurückgibt, die von der echten Prozedur zurückgegeben wurden, den Assistenten ausführen und dann die echte Prozedur zurücksetzen.
- Vorübergehend
SET FMTONLY OFF;
als erste Zeile in der PROC hinzufügen - das wird die Ausführung der PROC erzwingen. Setzen Sie die ursprüngliche PROC wieder zurück, wenn Sie fertig sind (wobei Ihre PROC möglicherweise wegen vom Tool übergebenen Null- oder Platzhalterparametern fehlschlagen kann). Außerdem wird FMTONLY
abgeschafft
- Am Anfang der PROC ein Dummy-Statement hinzufügen, das das tatsächliche Schema des/die zurückgegebenen Ergebnisset/s zurückgibt, eingebettet in einen bedingten Zweig, der niemals ausgeführt wird.
Hier ist ein Beispiel für den letzten Hack:
CREATE PROCEDURE [dbo].[Get_Details_by_Type]
@isArchived varchar(10),
@Type varchar(50)
AS
BEGIN
-- Nur für Tools mit FMTONLY ON
IF 1 = 2
BEGIN
-- Dies sind die tatsächlichen Spaltennamen und -typen, die von der echten Prozedur zurückgegeben werden
SELECT CAST('' AS NVARCHAR(20)) AS Col1,
CAST(0 AS DECIMAL(5,3)) AS Col2, ...
END;
-- Der Rest der eigentlichen PROC kommt hier
FMTONLY ON
/ sp_describe_first_result_set
werden vom Dummy-Bedingten getäuscht und gehen vom nie ausgeführten Zweig aus.
Außerdem würde ich empfehlen, aus Gründen Ihrer eigenen geistigen Gesundheit, dass Sie nicht SELECT *
in Ihrer PROC verwenden - listen Sie stattdessen explizit alle tatsächlichen Spaltennamen auf, die von Orders
zurückgegeben werden
Zum Schluss stellen Sie einfach sicher, dass Sie nicht die Anweisung SET FMTONLY ON;
in Ihrer PROC (aus Ihrem obigen Code!) einschließen
END - Proc
GO **
SET FMTONLY ON; ** Dies gehört nicht zur Proc!