web-dev-qa-db-fra.com

Comment puis-je rejoindre une procédure stockée?

J'ai une procédure stockée qui ne prend aucun paramètre et renvoie deux champs. La procédure stockée récapitule toutes les transactions appliquées à un locataire et renvoie le solde et l'identifiant du locataire.

Je souhaite utiliser le jeu d'enregistrements renvoyé avec une requête et je dois joindre ses résultats à l'identifiant du locataire.

Voici ma requête actuelle:

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 procédure stockée est la suivante:

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

Je voudrais également y ajouter le solde de la procédure stockée.

Comment puis-je faire ceci?

40
Malfist

En fait, j'aime bien la réponse précédente (n'utilisez pas le SP), mais si vous êtes lié au SP lui-même pour une raison quelconque, vous pouvez l'utiliser pour renseigner une table temporaire, puis rejoindre la table temporaire. . Notez que vous allez vous faire payer des frais généraux supplémentaires, mais c'est la seule façon dont je peux penser d'utiliser le processus stocké réel.

Là encore, il peut être préférable d’intégrer la requête du SP dans la requête initiale.

21
AllenG

insérez le résultat du SP dans une table temporaire, puis rejoignez:

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
...
40
devio

La réponse courte est "vous ne pouvez pas". Vous devrez soit utiliser une sous-requête, soit convertir votre procédure stockée existante en une fonction de table. Sa création en tant que fonction dépendra de la "réutilisabilité" dont vous auriez besoin.

17
CAbbott

Votre procédure stockée pourrait facilement être utilisée comme une vue. Ensuite, vous pouvez le joindre à tout ce dont vous avez besoin.

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

Le vous pouvez faire n'importe quelle déclaration comme:

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

J'ai résolu ce problème en écrivant la fonction à la place de la procédure et en utilisant CROSS APPLY dans l'instruction SQL. Cette solution fonctionne sur SQL 2005 et les versions ultérieures.

Gediminas Bukauskas

5

Il a déjà été répondu, la meilleure solution consiste à convertir la procédure stockée en une fonction SQL ou une vue.

La réponse courte, juste comme mentionné ci-dessus, est que vous ne pouvez pas directement joindre une procédure stockée dans SQL, à moins de créer une autre procédure stockée ou fonction en utilisant la sortie de la procédure stockée dans une table temporaire et JOINING la table temporaire, comme expliqué plus haut.

Je vais répondre à cette question en convertissant votre procédure stockée en une fonction SQL et en vous montrant comment l'utiliser dans une requête de votre choix.

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
)

Maintenant, pour utiliser cette fonction, dans votre 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

Si vous souhaitez transmettre des paramètres à votre fonction à partir du code SQL ci-dessus, je vous recommande d'utiliser CROSS APPLY ou CROSS OUTER APPLY.

Lisez ceci ici .

À votre santé

3
Fandango68

J'espère que votre procédure stockée ne fait pas une boucle de curseur!

Sinon, prenez la requête de votre procédure stockée et intégrez-la dans la requête que vous publiez ici:

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

Si vous effectuez autre chose qu'une requête dans votre procédure stockée, créez une table temporaire et exécutez-la dans cette table temporaire, puis rejoignez-la dans votre requête.

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
1
KM.

Voici une idée terrible pour vous.

Utilisez un alias, créez un nouveau serveur lié à partir de votre serveur vers son propre alias.

Maintenant vous pouvez faire:

select a.SomeColumns, b.OtherColumns
from LocalDb.dbo.LocalTable a
inner join (select * from openquery([AliasToThisServer],'
exec LocalDb.dbo.LocalStoredProcedure
') ) b
on a.Id = b.Id
0
Devin Lamothe

Pourquoi ne pas simplement effectuer le calcul dans votre 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
0