简体   繁体   English

如何加入存储过程?

[英]How can I join on a stored procedure?

I have a stored procedure that takes no parameters, and it returns two fields.我有一个不带参数的存储过程,它返回两个字段。 The stored procedure sums up all transactions that are applied to a tenant, and it returns the balance and the id of the tenant.该存储过程汇总了应用于租户的所有事务,并返回租户的余额和 ID。

I want to use the record set it returns with a query, and I need to join it's results on the id of the tenant.我想使用它通过查询返回的记录集,我需要在租户的 id 上加入它的结果。

This is my current query:这是我当前的查询:

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

The stored procedure is this:存储过程是这样的:

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

I would like to add the balance from the stored procedure to it also.我也想将存储过程中的余额添加到它。

How can I do this?我怎样才能做到这一点?

insert the result of the SP into a temp table, then join:将 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
...

I actually like the previous answer (don't use the SP), but if you're tied to the SP itself for some reason, you could use it to populate a temp table, and then join on the temp table.我实际上喜欢上一个答案(不要使用 SP),但是如果您出于某种原因与 SP 本身相关联,则可以使用它来填充临时表,然后加入临时表。 Note that you're going to cost yourself some additional overhead there, but it's the only way I can think of to use the actual stored proc.请注意,您将在那里花费一些额外的开销,但这是我能想到的使用实际存储过程的唯一方法。

Again, you may be better off in-lining the query from the SP into the original query.同样,最好将来自 SP 的查询内联到原始查询中。

The short answer is "you can't".简短的回答是“你不能”。 What you'll need to do is either use a subquery or you could convert your existing stored procedure in to a table function.您需要做的是使用子查询,或者您可以将现有的存储过程转换为表函数。 Creating it as function would depend on how "reusable" you would need it to be.将其创建为函数将取决于您需要它的“可重用性”。

Your stored procedure could easily be used as a view instead.您的存储过程可以轻松地用作视图。 Then you can join it on to anything else you need.然后你可以将它加入到你需要的任何其他东西上。

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

The you can do any statement like:您可以执行任何语句,例如:

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

I resolved this problem writing function instead of procedure and using CROSS APPLY in SQL statement.我解决了编写函数而不是过程并在 SQL 语句中使用 CROSS APPLY 的问题。 This solution works on SQL 2005 and later versions.此解决方案适用于 SQL 2005 及更高版本。

It has already been answered, the best way work-around is to convert the Stored Procedure into an SQL Function or a View.已经回答了,最好的解决方法是将存储过程转换为 SQL 函数或视图。

The short answer, just as mentioned above, is that you cannot directly JOIN a Stored Procedure in SQL, not unless you create another stored procedure or function using the stored procedure's output into a temporary table and JOINing the temporary table, as explained above.正如上面提到的,简短的回答是,您不能直接在 SQL 中加入存储过程,除非您使用存储过程的输出创建另一个存储过程或函数到临时表中并加入临时表,如上所述。

I will answer this by converting your Stored Procedure into an SQL function and show you how to use it inside a query of your choice.我将通过将您的存储过程转换为 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
)

Now to use that function, in your SQL...现在要在您的 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

If you wish to pass parameters into your function from within the above SQL, then I recommend you use CROSS APPLY or CROSS OUTER APPLY .如果您希望从上述 SQL 中将参数传递到您的函数中,那么我建议您使用CROSS APPLYCROSS OUTER APPLY

Read up on that here .这里阅读。

Cheers干杯

I hope your stored procedure is not doing a cursor loop!我希望您的存储过程没有执行游标循环!

If not, take the query from your stored procedure and integrate that query within the query you are posting here:如果没有,请从您的存储过程中获取查询并将该查询集成到您在此处发布的查询中:

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

If you are doing something more than a query in your stored procedure, create a temp table and execute the stored procedure into this temp table and then join to that in your 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

Here's a terrible idea for you.这是一个可怕的主意。

Use an alias, create a new linked server from your server to its own alias.使用别名,从你的服务器创建一个新的链接服务器到它自己的别名。

Now you can do:现在你可以这样做:

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

Why not just performing the calculation in your SQL?为什么不在您的 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM