risposta-alla-domanda-sullo-sviluppo-web-bd.com

Utilizzare SQL per filtrare i risultati di una stored procedure

Ho esaminato altre domande su Stack Overflow relative a questa domanda, ma nessuna sembrava rispondere a questa domanda in modo chiaro.

Abbiamo una stored procedure di sistema denominata sp_who2 che restituisce un set di risultati di informazioni per tutti i processi in esecuzione sul server. Voglio filtrare i dati restituiti dalla stored procedure; concettualmente, potrei farlo in questo modo:

SELECT * FROM sp_who2
WHERE login='bmccormack'

Questo metodo, però, non funziona. Quali sono le buone pratiche per raggiungere l'obiettivo di interrogare i dati restituiti di una stored procedure, preferibilmente senza dover guardare il codice della stored procedure originale e modificarlo.

29
Ben McCormack

Non ci sono buoni modi per farlo. È una limitazione delle stored procedure. Le tue opzioni sono:

  1. Passare la procedura a Funzione definita dall'utente . In tutto il mondo, oggi, le persone stanno facendo stored procedure che dovrebbero essere funzioni. È un problema educativo. La tua situazione è un buon esempio perché. Se la tua procedura fosse invece una UDF, potresti semplicemente fare quanto segue, esattamente come pensi intuitivamente di dover essere in grado di:

    SELECT * FROM udf_who2()
    WHERE login='bmccormack'
    
  2. Se davvero non riesci a toccare la tua procedura, e must hai fatto questo in sql, allora dovrai fare il funky. Crea un'altra stored procedure per completare la procedura originale. All'interno della tua nuova procedura chiama la tua procedura esistente e metti i valori in una tabella temporanea, quindi esegui una query su quella tabella con il filtro che desideri e restituisci quel risultato al mondo esterno.

A partire da SQL Server 2005, le funzioni definite dall'utente sono il modo in cui si incapsula il recupero dei dati. Le stored procedure, insieme a Views, sono strumenti speciali da utilizzare in determinate situazioni. Sono entrambi molto utili al momento giusto, ma non la prima scelta. Alcuni potrebbero pensare che l'esempio precedente (A) ottenga tutti i risultati della funzione e poi i (B) filtri su quel gruppo di risultati, come una sottoquery. Questo non è il caso . SQL Server 2005+ ottimizza tale query; se esiste un indice su login, non viene visualizzata una scansione della tabella nel piano di esecuzione della query; molto efficiente.

Edit : Dovrei aggiungere che le componenti interne di una UDF sono simili a quelle di un SP. Se si ha a che fare con logica del SP che si desidera evitare, è comunque possibile cambiarlo in una funzione. Diverse volte ho preso codice di procedure grandi e spaventose che non volevo capire e ho trasferito con successo a una funzione. L'unico problema sarà se la procedura modifica qualcosa oltre a restituire risultati; Le UDF non possono modificare i dati nel db. 

29
Patrick Karcher

Il filtraggio del tavolo temporaneo è il modo possibile.

-- 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

È possibile eseguire OPENROWSET(), ma sono presenti alcuni problemi di sicurezza/prestazioni.

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

Tradizionalmente, l'aggiunta a una variabile temporanea/tabella funzionerà.

12
bryanjonker

Posiziona i dati in una variabile Table o Temp table e filtrati su di esso.

3
Fahad

OPENROWSET () è il modo:

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

Inoltre è necessario abilitare la configurazione preliminare prima di lavorare:

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