Sql 如何加入存储过程?

Sql 如何加入存储过程?,sql,sql-server-2005-express,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 JO

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


我怎样才能做到这一点?

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

我希望您的存储过程没有执行游标循环

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

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

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

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


同样,最好将来自SP的查询与原始查询对齐。

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

您的存储过程可以轻松地用作视图。然后你可以把它连接到你需要的任何东西上

SQL:

您可以执行以下任何语句:

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

我解决了这个问题,用编写函数代替过程,并在SQL语句中使用交叉应用。此解决方案适用于SQL 2005及更高版本。

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

请仔细阅读


干杯

给你一个糟糕的主意

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

现在您可以执行以下操作:

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

你的问题和你的示例代码没有联系——你谈论的是事务和用户;此示例是关于租户和租赁属性的。租户=用户。我想在查询中添加余额,因为它是用于报告的,而且它还需要租户居住的房产的所有信息。另外,为什么要在租赁单元和房产表之间使用左外连接?你不应该让你的数据库处于这样一种引用无关的状态,以至于可能需要它(你应该在租赁单元和属性之间有一个外键约束,以防止租赁单元中出现无效代码)。对不起,这是一个输入错误。谢谢你接电话。这些表是链接到Tenant->Rental Unit->Property的。您对SP的描述意味着它返回一行—但我从进一步的讨论中了解到,它返回一个结果集,每个租户一行。实际上,它返回一个表。由于您使用的是SQL Server,我不知道是否有办法让它将SP的结果集作为表处理。在至少一个其他DBMS中,您可以使用TABLE(MULTISET(EXECUTE FUNCTION spname())作为别名(Balance,ID)作为FROM子句的一部分。我问的是如何集成SP,因为我不知道我如何相信SP正在执行游标循环,我不希望将其内联,因为如果我确实更改了SP,我将必须查找所有内联的内容并进行更改too@Malfist,如果您坚持它是一个SP而不是一个函数或内联,那么您唯一的选择就是AllenG建议的,填充一个临时表并在该表上进行连接。尝试使用一个表变量而不是临时表。@AllenG很抱歉,但这不是答案。“不要使用SP”是指避免使用交叉应用程序进行操作,但如果这不起作用,那么答案应该是“不,你不能这样做。”句号。说避免使用SP并将逻辑更改为函数并不是答案返回表的UDF(用户定义函数)会非常有用。你说使用“子查询”。这不是一个解决办法吗?请用一些代码解释一下你的意思?谢谢,我想你会发现这是一个比使用临时表更好的答案,因为它仍然是一段集中的代码,只需要在一个地方进行更新,并且没有创建临时表,然后插入临时表,然后从临时表中选择返回的开销。好可怕的主意,我从来没有想到过
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