我如何加入存储过程?

时间:2009-05-28 14:38:54

标签: sql sql-server-2005-express

我有一个不带参数的存储过程,它返回两个字段。存储过程汇总了应用于租户的所有事务,并返回租户的余额和ID。

我想使用它返回的记录集和查询,我需要将其结果加入租户的id。

这是我目前的查询:

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

存储过程是这样的:

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

我想将存储过程中的余额添加到它。

我该怎么做?

9 个答案:

答案 0 :(得分:42)

将SP的结果插入临时表,然后加入:

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

答案 1 :(得分:23)

我实际上喜欢上一个答案(不要使用SP),但是如果由于某种原因你被绑定到SP本身,你可以使用它来填充临时表,然后加入临时表。请注意,您将花费一些额外的开销,但这是我能够考虑使用实际存储过程的唯一方法。

同样,您可能最好将查询从SP内嵌到原始查询中。

答案 2 :(得分:18)

简短的回答是“你不能”。您需要做的是使用子查询,或者您可以将现有的存储过程转换为表函数。将其创建为函数将取决于您将需要它的“可重用”。

答案 3 :(得分:9)

您的存储过程可以轻松地用作视图。然后你可以将它加入到你需要的任何其他东西中。

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

你可以做任何声明,如:

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

答案 4 :(得分:6)

我解决了这个问题,编写函数而不是过程,并在SQL语句中使用CROSS APPLY。此解决方案适用于SQL 2005及更高版本。

Gediminas Bukauskas

答案 5 :(得分:4)

已经得到解答,最好的解决方法是将存储过程转换为SQL函数或视图。

如上所述,简短的回答是,您不能直接在SQL中加入存储过程,除非您使用存储过程输出到临时表中创建另一个存储过程或函数并加入临时表表,如上所述。

我将通过将您的存储过程转换为SQL函数来回答这个问题,并向您展示如何在您选择的查询中使用它。

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
)

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

如果您希望从上述SQL中将参数传递到您的函数中,我建议您使用CROSS APPLYCROSS OUTER APPLY

阅读here

干杯

答案 6 :(得分:2)

我希望你的存储过程没有进行游标循环!

如果没有,请从存储过程中获取查询,并将该查询集成到您在此处发布的查询中:

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

如果您在存储过程中执行的操作不仅仅是查询,请创建临时表并将存储过程执行到此临时表中,然后再连接到查询中的那个。

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

答案 7 :(得分:0)

为什么不在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

答案 8 :(得分:0)

这对你来说是个可怕的主意。

使用别名,从服务器到其自己的别名创建一个新的链接服务器。

现在您可以这样做:

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