Mein Szenario
Ich arbeite an einer Datenbank, die viele Details aus verschiedenen Stored Procedures in verschiedenen Datenbanken auf dem gesamten Server enthalten wird. Die Informationen, die ich jetzt zu sammeln versuche, sind: "Was gibt die SP aus?"
Bei der Suche habe ich festgestellt, dass die Antwort in OPENROWSET liegt. Meine ersten Tests waren erfolgreich und alles sah gut aus. Beim Testen mit Live-SPs stieß ich jedoch auf ein großes Problem: Es funktioniert nicht gut mit temporären (#) Tabellen.
Zum Beispiel:
Wenn ich diese SP nehmen würde:
CREATE PROCEDURE dbo.zzTempSP(@A INT, @B INT) AS
SELECT @A AS A, @B AS B
Mit dem folgenden Code kann ich die Ausgabe leicht in eine temp (##)-Tabelle einfügen, dann die sysobjects von tempdb abfragen und eine Liste der Spalten und ihrer Datentypen erstellen:
IF OBJECT_ID('tempdb.dbo.##TempOutput','U') IS NOT NULL DROP TABLE ##TempOutput
DECLARE @sql VARCHAR(MAX)
SELECT @sql = 'SELECT *
INTO ##TempOutput
FROM OPENROWSET(''SQLNCLI'', ''Server=' +
CONVERT(VARCHAR(100), SERVERPROPERTY('MachineName')) +
';Trusted_Connection=yes;'', ''SET FMTONLY OFF exec ' +
DB_NAME() +
'.dbo.zzTempSP @A=1, @B=2'')'
EXEC(@sql)
SELECT *
FROM ##TempOutput
Großartig! Allerdings, wenn die SP war dies statt:
CREATE PROCEDURE dbo.zzTempSP (@A INT, @B INT) AS CREATE TABLE dbo.#T (A INT, B INT)
INSERT INTO dbo.#T
SELECT @A AS A, @B AS B
SELECT *
FROM dbo.#T
Wenn ich die gleiche OPENROWSET
Code wie zuvor erhalte ich den folgenden Fehler:
Das Objekt "SET FMTONLY OFF exec DatabaseName.dbo.zzTempSP @A=1,@B=2" kann nicht verarbeitet werden. Der OLE DB-Anbieter "SQLNCLI10" für den verknüpften Server "(null)" zeigt an, dass entweder das Objekt keine Spalten hat oder der aktuelle Benutzer keine Berechtigungen für dieses Objekt hat.
Wenn ich den OPENROWSET-Code (durch Entfernen des dynamischen Zeugs) auf Folgendes reduziere:
SELECT *
FROM OPENROWSET('SQLNCLI','Server=ServerName;Trusted_Connection=yes;',
'exec DatabaseName.dbo.zzTempSP @A=1,@B=2'
)
Ich erhalte den folgenden (viel nützlicheren) Fehler:
Ungültiger Objektname '#T'.
Und da bin ich gegen die Wand gefahren. Bei meinen Recherchen stellte sich heraus, dass es keine Lösung gibt, aber ich konnte mich nicht dazu durchringen, einfach aufzugeben.
Und so werde ich dazu verleitet
Meine Frage an Sie
Ist jemandem eine Möglichkeit bekannt, diesen Fehler zu umgehen? Oder gibt es möglicherweise eine alternative Lösung?
Dieser Prozess wird nicht häufig ausgeführt, so dass ich mir keine allzu großen Sorgen um die Effizienz der Lösung machen muss.
Jeder Beitrag wäre sehr willkommen.
Danke! Zok
PS: Entschuldigung für die Formatierung. Ich habe die Sprachtags nicht ganz verstanden.
0 Stimmen
Ich glaube, ich habe einen Weg gefunden, der die Verwendung von SET NOCOUNT ON beinhaltet. Als ich es zu meinem Dummy-SP hinzufügte, funktionierte es, aber nicht bei dem, den ich tatsächlich verwenden werde (der diese Zeile bereits enthielt). Ich werde weiter damit herumspielen und berichten, was ich herausfinde.
0 Stimmen
In der gleichen Führung, die ich oben erwähnt habe, mussten sie ein No Op für die SP einführen. Ich habe in Erwägung gezogen, eine Zwischenprozedur zu erstellen, die den SP analysiert, aus dem wir versuchen, Details zu sammeln (über Syscomments) und die Definition der temporären Tabelle herauszieht, um dynamisch ein No Op zu erstellen, aber ich sehe viele Probleme, die schwer zu umgehen wären. Soooooo, ich bin immer noch im selben Boot.
0 Stimmen
Eine großartige Leistung von Ihnen....danke