it-swarm.com.de

Verwenden Sie SQL, um die Ergebnisse einer gespeicherten Prozedur zu filtern

Ich habe mir andere Fragen zu Stack Overflow im Zusammenhang mit dieser Frage angesehen, aber keine von ihnen schien diese Frage klar zu beantworten.

Wir haben eine gespeicherte Systemprozedur namens sp_who2, die eine Ergebnismenge von Informationen für alle laufenden Prozesse auf dem Server zurückgibt. Ich möchte die von der gespeicherten Prozedur zurückgegebenen Daten filtern. Konzeptuell könnte ich es so machen:

SELECT * FROM sp_who2
WHERE login='bmccormack'

Diese Methode funktioniert jedoch nicht. Was sind bewährte Methoden, um das Ziel zu erreichen, die zurückgegebenen Daten einer gespeicherten Prozedur abzufragen, vorzugsweise ohne den Code der ursprünglichen gespeicherten Prozedur suchen und ändern zu müssen.

29
Ben McCormack

Es gibt keine guten Möglichkeiten, dies zu tun. Dies ist eine Einschränkung für gespeicherte Prozeduren. Ihre Optionen sind:

  1. Wechseln Sie die Prozedur auf eine Benutzerdefinierte Funktion . Auf der ganzen Welt machen die Menschen heute gespeicherte Prozeduren, die Funktionen sein sollten. Es ist ein Bildungsproblem. Ihre Situation ist ein gutes Beispiel dafür. Wenn Ihre Prozedur statt einer UDF wäre, könnten Sie einfach Folgendes tun, genau so, wie Sie es intuitiv glauben sollten:

    SELECT * FROM udf_who2()
    WHERE login='bmccormack'
    
  2. Wenn Sie Ihre Prozedur wirklich nicht anfassen können und muss dies in SQL erledigt haben, müssen Sie funky werden. Erstellen Sie eine andere gespeicherte Prozedur, um Ihre ursprüngliche Prozedur einzuwickeln. Rufen Sie in Ihrer neuen Prozedur Ihre vorhandene Prozedur auf, legen Sie die Werte in einer temporären Tabelle ab, führt eine Abfrage mit dieser Tabelle mit dem gewünschten Filter aus und geben Sie das Ergebnis an die Außenwelt zurück.

Ab SQL Server 2005 können Sie mithilfe von benutzerdefinierten Funktionen den Datenabruf einkapseln. Gespeicherte Prozeduren sind zusammen mit Ansichten Spezialwerkzeuge, die in bestimmten Situationen verwendet werden können. Beide sind zum richtigen Zeitpunkt sehr praktisch, aber nicht die erste Wahl. Einige denken vielleicht, dass das obige Beispiel (A) alle Ergebnisse der Funktion abruft und dann (B) diese Ergebnismenge wie eine Unterabfrage filtert. Dies ist nicht der Fall . SQL Server 2005+ optimiert diese Abfrage. Wenn für login ein Index vorhanden ist, wird im Abfrageausführungsplan kein Tabellenscan angezeigt. sehr effizient.

Edit : Ich sollte hinzufügen, dass das Innern einer UDF dem eines SP ähnelt. Wenn Sie mit dem Logik des SP umgehen, das Sie vermeiden möchten, können Sie es immer noch in eine Funktion umwandeln. Mehrmals habe ich großen, unheimlichen Prozedurcode genommen, den ich nicht verstehen wollte, und ihn erfolgreich in eine Funktion übertragen. Das einzige Problem wird sein, wenn die Prozedur modifiziert etwas zusätzlich zu den Ergebnissen zurückgibt; UDFs können keine Daten in der Datenbank ändern. 

29
Patrick Karcher

Das Filtern von temporären Tabellen ist der mögliche Weg.

-- Create tmp table from sp_who results
CREATE TABLE #TmpWho
(spid INT, ecid INT, status VARCHAR(150), loginame VARCHAR(150),
hostname VARCHAR(150), blk INT, dbname VARCHAR(150), cmd VARCHAR(150), request_id INT)
INSERT INTO #TmpWho
EXEC sp_who

-- filter temp table where spid is 52
SELECT * FROM #TmpWho
WHERE spid = 52

DROP TABLE #TmpWho
13
Petr Dostál

Sie können eine OPENROWSET() ausführen, es gibt jedoch einige Sicherheits-/Leistungsprobleme.

SELECT * 
FROM OPENROWSET ('SQLOLEDB', 'Server=(local);TRUSTED_CONNECTION=YES;', 'exec mystoredproc')

Das Hinzufügen zu einer temporären Variablen/Tabelle wird normalerweise funktionieren.

12
bryanjonker

Platzieren Sie die Daten in einer Table-Variablen oder Temp-Tabelle und filtern Sie sie.

3
Fahad

OPENROWSET () ist der Weg:

SELECT *
FROM
    OPENROWSET('SQLNCLI', 'Server=(local);TRUSTED_CONNECTION=YES;', 'exec sp_who')
WHERE loginame = 'test' AND dbname = 'Expirement';

Außerdem müssen Sie die Vorauskonfiguration aktivieren, bevor Sie arbeiten können:

sp_configure 'show advanced options', 1;  
RECONFIGURE;
GO
sp_configure 'Ad Hoc Distributed Queries', 1; 
RECONFIGURE;
GO 
0
Lei Chi