55

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

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

我怎样才能做到这一点?

4

9 回答 9

53

将 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
...
于 2009-05-28T15:03:25.940 回答
31

我实际上喜欢上一个答案(不要使用 SP),但是如果您出于某种原因与 SP 本身相关联,则可以使用它来填充临时表,然后加入临时表。请注意,您将在那里花费一些额外的开销,但这是我能想到的使用实际存储过程的唯一方法。

同样,您最好将来自 SP 的查询内联到原始查询中。

于 2009-05-28T14:55:45.487 回答
20

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

于 2009-05-28T14:53:03.777 回答
11

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

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
于 2009-05-28T15:43:54.297 回答
7

已经回答了,最好的解决方法是将存储过程转换为 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 APPLYor CROSS OUTER APPLY

在这里阅读。

干杯

于 2016-08-29T05:00:00.767 回答
6

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

于 2009-08-09T10:30:39.583 回答
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
于 2009-05-28T14:55:30.840 回答
1

这对你来说是个糟糕的主意。

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

现在你可以这样做:

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
于 2018-10-10T01:38:42.570 回答
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
于 2009-05-28T14:55:35.723 回答