Für Ein- und Ausgangsparameter können Sie sehen sys.parameters
, sys.procedures
und sys.types
. Hier ist eine Prozedur mit verschiedenen Eingabe- / Ausgabeparametern, Alias-Typen und sogar einem TVP (nur 2008+):
USE [tempdb];
GO
CREATE TYPE dbo.TVPType AS TABLE(id INT);
GO
CREATE PROCEDURE dbo.foobar
@a INT,
@b SYSNAME = N'foo',
@c DATETIME = NULL,
@d dbo.TVPType READONLY,
@e NVARCHAR(MAX),
@f INT OUTPUT,
@g INT = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT @f = COUNT(*) FROM sys.objects;
END
GO
Und hier ist eine Abfrage, um diese Informationen abzurufen sys.parameters
, sys.procedures
und sys.types
:
SELECT
s = QUOTENAME(OBJECT_SCHEMA_NAME(p.[object_id])),
o = QUOTENAME(p.name),
p = pr.name,
t1.name,
pr.max_length,
pr.[precision],
pr.scale,
pr.is_output,
pr.is_readonly
FROM sys.procedures AS p
INNER JOIN sys.parameters AS pr
ON p.[object_id] = pr.[object_id]
LEFT OUTER JOIN sys.types AS t1
ON (pr.system_type_id = t1.system_type_id)
AND (pr.system_type_id <> t1.system_type_id
OR pr.user_type_id = t1.user_type_id)
WHERE p.[object_id] = OBJECT_ID('dbo.foobar')
ORDER BY pr.parameter_id;
Ergebnisse:
s o p name max_length [precision] scale is_output is_readonly
----- ---------- --- -------- --------- ----------- ----- --------- -----------
[dbo] [foobar] @a int 4 10 0 0 0
[dbo] [foobar] @b sysname 256 0 0 0 0
[dbo] [foobar] @c datetime 8 23 3 0 0
[dbo] [foobar] @d TVPType -1 0 0 0 1
[dbo] [foobar] @e nvarchar -1 0 0 0 0
[dbo] [foobar] @f int 4 10 0 1 0
[dbo] [foobar] @g int 4 10 0 1 0
Offensichtlich müssen Sie einige Massagen durchführen, damit diese Werte wie echte Datentypen aussehen. Schneiden Sie beispielsweise die max_length eines nvarchar in zwei Hälften, es sei denn, es ist -1. In diesem Fall muss es ausgetauscht werden MAX
. Fügen Sie für Dezimalzahlen, Zahlen usw. die Genauigkeit und Skalierung entsprechend hinzu. Wenn Sie TVPs verwenden, möchten Sie wahrscheinlich das Schema SCHEMA_NAME
für diese Typen abrufen. Usw. usw.
Leider gibt es keine andere Möglichkeit als Brute-Force-Analyse des Prozedurkörpers (und selbst das ist ohne ernsthafte Ninja-RegEx-Kenntnisse nicht trivial), um festzustellen, ob der Parameter nullwertfähig ist oder ob er einen Standardwert hat und wie der Standardwert lautet. Diese Informationen werden einfach nicht in den Metadaten gespeichert - während sie vorhanden sind has_default_value
und default_value
Spalten enthalten sys.parameters
, sind sie NULL
für CLR-Prozeduren immer nur ungleich oder ungleich Null. Ich habe mich seit 2006 darüber beschwert, aber wir haben noch keine Fortschritte in diesem Bereich zu sehen (obwohl ich eine Problemumgehung für dieses Connect-Element veröffentlicht habe, die ich hier nicht reproduzieren werde, da einige unangemessene Annahmen über den Codierungsstil Ihrer gespeicherten Prozeduren getroffen werden). Und es gibt überhaupt nichts, was Hoffnung gibt, festzustellen, ob der Parameter optional ist (z . B. @c
und @g
höher).
Bei den Ergebnismengen hat Martin völlig Recht - es gibt keine zuverlässige Methode, um herauszufinden, woraus ein Ergebnis bestehen wird, außer die Verwendung SET FMTONLY ON
. Es gibt einige eigenartige Fehler bei diesem, also würde ich mich davon fernhalten. Eine beliebte Flickschusterei ist die Verwendung OPENQUERY
mit einem „Loopback“ verknüpften Server , wählen Sie die Ergebnisse in eine #temp Tabelle, aber das funktioniert nur , wenn die Prozedur genau ein resultset hat. Ein gutes Beispiel findet sich in einer der vorherigen Antworten von Martin:
Was ist der einfachste Weg, um eine temporäre Tabelle in SQL Server zu erstellen, die das Ergebnis einer gespeicherten Prozedur enthalten kann?
Sobald Sie die Ausgabe in die Tabelle #temp eingefügt haben, können Sie Folgendes ausführen:
EXEC tempdb..sp_help '#tablename';
Dies gibt unter anderem eine Liste von Spaltennamen und deren Datentypen aus. Während dies für Hunderte von gespeicherten Prozeduren ein langwieriger Prozess sein wird, habe ich Ideen zur Automatisierung. Wenn dies für Sie eine interessante Lösung ist, lassen Sie es mich bitte wissen und ich kann meine Antwort erweitern.
Martin auch neue Funktionen in SQL Server 2012 angedeutet , dass dies ein machen wird viel einfacher (aber es ist immer noch auf den ersten resultset einer gespeicherten Prozedur begrenzt). Weitere Details dazu finden Sie in meiner Antwort auf dieselbe Frage oben.
Für Rückgabewerte kenne ich keine Möglichkeit, diese aus den Metadaten abzurufen.