2009-05-28 17 views
34

Ho una stored procedure che non accetta parametri e restituisce due campi. La procedura memorizzata riassume tutte le transazioni applicate a un titolare e restituisce il saldo e l'ID del titolare.Come posso partecipare a una stored procedure?

voglio usare il record stabilito ritorna con una query, e ho bisogno di farne parte di risultati sul id del locatario.

Questa è la mia query corrente:

SELECT t.TenantName, t.CarPlateNumber, t.CarColor, t.Sex, t.SSNO, t.Phone, t.Memo, 
     u.UnitNumber, 
     p.PropertyName 
FROM tblTenant t 
    LEFT JOIN tblRentalUnit u 
    ON t.UnitID = u.ID 

    LEFT JOIN tblProperty p 
    ON u.PropertyID = p.ID 

ORDER BY p.PropertyName, t.CarPlateNumber 

La stored procedure è questo:

SELECT tenant.ID AS TenantID, SUM(ISNULL(trans.Amount,0)) AS TenantBalance FROM tblTenant tenant 
    LEFT JOIN tblTransaction trans 
    ON tenant.ID = trans.TenantID 
    GROUP BY tenant.ID 

vorrei aggiungere la bilancia dalla stored procedure ad esso anche.

Come posso fare questo?

+0

La tua domanda e il tuo codice di esempio non vincolano: parli di transazioni e utenti; il campione riguarda gli inquilini e le proprietà in affitto. –

+0

tenant = utenti. Desidero aggiungere un equilibrio alla query perché è per un report e ha bisogno di tutte le informazioni sulla proprietà in cui vive anche l'inquilino. – Malfist

+0

Inoltre, perché dovresti utilizzare un JOINT OUTER SINISTRO tra l'unità di noleggio e le tabelle delle proprietà? Non dovresti lasciare che il tuo database si trovi in ​​tale stato di disintegrazione referenziale che potrebbe esserci un bisogno (dovresti avere un vincolo di chiave esterna tra unità di noleggio e proprietà che impedisce codici non validi nell'unità di noleggio). –

risposta

20

Io in realtà come la risposta precedente (non utilizzare la SP), ma se siete vincolati alla stessa SP per qualche motivo, si potrebbe utilizzare per popolare una tabella temporanea, e poi unire il la tabella temporanea. Nota che ti stai pagando un po 'di overhead aggiuntivo, ma è l'unico modo in cui posso pensare di usare il proc reale memorizzato.

Anche in questo caso, si può essere meglio in-fodera la query dalla SP nella query originale.

+3

Preferirei non inserirlo, perché poi se cambio l'SP, lo farò devo dare la caccia ovunque l'ho delineato e cambiarlo anch'io – Malfist

+1

@Malfist, se insisti che sia una SP invece di una funzione o inline, la tua unica opzione è ciò che AllenG suggerisce, popola una tabella temporanea e unisciti a quella. –

+0

Provare a utilizzare una variabile di tabella anziché una tabella temporanea. – David

16

La risposta breve è "non si può". Quello che devi fare è usare una subquery o convertire la tua stored procedure esistente in una funzione di tabella. La sua creazione come funzione dipenderebbe da quanto "riutilizzabile" avresti bisogno che fosse.

+1

Una UDF (funzione definita dall'utente) che restituisce una tabella sarebbe incredibilmente utile. – TheTXI

+1

Hai detto di utilizzare una "query secondaria". Beh, non è una soluzione? Per favore, spiega cosa intendevi con un codice?Grazie – Fandango68

1

spero stored procedure non sta facendo un ciclo cursore!

Altrimenti, la query dalla stored procedure e integrare quella query all'interno della query stai scrivendo qui:

SELECT t.TenantName, t.CarPlateNumber, t.CarColor, t.Sex, t.SSNO, t.Phone, t.Memo, 
     u.UnitNumber, 
     p.PropertyName 
     ,dt.TenantBalance 
FROM tblTenant t 
    LEFT JOIN tblRentalUnit u ON t.UnitID = u.ID 
    LEFT JOIN tblProperty p ON u.PropertyID = p.ID 
    LEFT JOIN (SELECT ID, SUM(ISNULL(trans.Amount,0)) AS TenantBalance 
        FROM tblTransaction 
        GROUP BY tenant.ID 
      ) dt ON t.ID=dt.ID 
ORDER BY p.PropertyName, t.CarPlateNumber 

Se stai facendo qualcosa di più di una query in stored procedure, creare una temperatura tabella ed eseguire la procedura memorizzata in questa tabella temporanea e quindi partecipare a quella nella query.

create procedure test_proc 
as 
    select 1 as x, 2 as y 
    union select 3,4 
    union select 5,6 
    union select 7,8 
    union select 9,10 
    return 0 
go 

create table #testing 
(
    value1 int 
    ,value2 int 
) 

INSERT INTO #testing 
exec test_proc 


select 
    * 
    FROM #testing 
+0

Sto chiedendo come integrare l'SP, perché non so come – Malfist

+0

Credo che l'SP stia facendo un ciclo di cursore – Malfist

0

Perché non eseguire il calcolo nel proprio SQL?

SELECT 
    t.TenantName 
    , t.CarPlateNumber 
    , t.CarColor 
    , t.Sex 
    , t.SSNO 
    , t.Phone 
    , t.Memo 
    , u.UnitNumber 
    , p.PropertyName 
    , trans.TenantBalance 
FROM tblTenant t 
    LEFT JOIN tblRentalUnit u ON t.UnitID = u.ID 
    LEFT JOIN tblProperty p ON u.PropertyID = p.ID 
    INNER JOIN (
     SELECT tenant.ID AS TenantID, SUM(ISNULL(trans.Amount,0)) AS TenantBalance 
     FROM tblTenant tenant 
      LEFT JOIN tblTransaction trans ON tenant.ID = trans.TenantID 
     GROUP BY tenant.ID 
    ) trans ON trans.ID = t.ID 
ORDER BY 
    p.PropertyName 
    , t.CarPlateNumber 
33

inserire il risultato della SP in una tabella temporanea, poi unirsi:

CREATE TABLE #Temp (
    TenantID int, 
    TenantBalance int 
) 

INSERT INTO #Temp 
EXEC TheStoredProc 

SELECT t.TenantName, t.CarPlateNumber, t.CarColor, t.Sex, t.SSNO, t.Phone, t.Memo, 
    u.UnitNumber, p.PropertyName 
FROM tblTenant t 
INNER JOIN #Temp ON t.TenantID = #Temp.TenantID 
... 
8

stored procedure potrebbe essere facilmente utilizzato come una visione, invece. Quindi puoi unirti a qualsiasi altra cosa di cui hai bisogno.

SQL:

CREATE VIEW vwTenantBalance 
AS 

SELECT tenant.ID AS TenantID, SUM(ISNULL(trans.Amount,0)) AS TenantBalance 
FROM tblTenant tenant 
LEFT JOIN tblTransaction trans 
ON tenant.ID = trans.TenantID 
GROUP BY tenant.ID 

La si può fare qualsiasi dichiarazione come:

SELECT t.TenantName, t.CarPlateNumber, t.CarColor, t.Sex, t.SSNO, t.Phone, 
    t.Memo, u.UnitNumber, p.PropertyName, TenantBalance 
FROM tblTenant t 
LEFT JOIN tblRentalUnit u 
ON t.UnitID = u.ID 
LEFT JOIN tblProperty p 
ON u.PropertyID = p.ID 
LEFT JOIN vwTenantBalance v 
ON t.ID = v.tenantID 
ORDER BY p.PropertyName, t.CarPlateNumber 
+0

@ck: puoi mostrare come si farebbe? –

+0

@John Saunders: aggiornato con il codice – cjk

+1

Penso che troverete che questa è una risposta molto migliore rispetto all'utilizzo di una tabella temporanea in quanto è ancora un pezzo di codice centralizzato che avrà sempre e solo bisogno di essere aggiornato in un unico posto, e non ha sovraccarico della creazione di una tabella temporanea, quindi l'inserimento in essa, quindi la selezione di fuori di esso. – cjk

5

ho risolto questo problema funzione invece di procedura di scrittura e usando CROSS APPLY in SQL. Questa soluzione funziona su SQL 2005 e versioni successive.

Gediminas Bukauskas

2

E 'già stato risposto, il miglior modo work-around è quello di convertire la stored procedure in una funzione SQL o una visualizzazione.

La risposta breve, come detto sopra, è che non è possibile accedere direttamente a una stored procedure in SQL, a meno che non si crei un'altra procedura memorizzata o una funzione utilizzando l'output della stored procedure in una tabella temporanea e che si uniscano alla tabella temporanea, come spiegato sopra.

Risponderò a questo convertendo la stored procedure in una funzione SQL e mostrandovi come utilizzarla all'interno di una query di vostra scelta.

CREATE FUNCTION fnMyFunc() 
RETURNS TABLE AS 
RETURN 
(
    SELECT tenant.ID AS TenantID, 
     SUM(ISNULL(trans.Amount,0)) AS TenantBalance 
    FROM tblTenant tenant 
    LEFT JOIN tblTransaction trans ON tenant.ID = trans.TenantID 
    GROUP BY tenant.ID 
) 

Ora per utilizzare tale funzione, in SQL ...

SELECT t.TenantName, 
     t.CarPlateNumber, 
     t.CarColor, 
     t.Sex, 
     t.SSNO, 
     t.Phone, 
     t.Memo, 
     u.UnitNumber, 
     p.PropertyName 
FROM tblTenant t 
    LEFT JOIN tblRentalUnit u ON t.UnitID = u.ID 
    LEFT JOIN tblProperty p ON u.PropertyID = p.ID 
    LEFT JOIN dbo.fnMyFunc() AS a 
     ON a.TenantID = t.TenantID 
ORDER BY p.PropertyName, t.CarPlateNumber 

Se si desidera passare parametri nella vostra funzione all'interno del SQL sopra, allora vi consiglio di usare CROSS APPLY o CROSS OUTER APPLY.

Leggere su quello here.

Cheers

Problemi correlati