簡體   English   中英

如何加入存儲過程?

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

我有一個不帶參數的存儲過程,它返回兩個字段。 該存儲過程匯總了應用於租戶的所有事務,並返回租戶的余額和 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

我也想將存儲過程中的余額添加到它。

我怎樣才能做到這一點?

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

我實際上喜歡上一個答案(不要使用 SP),但是如果您出於某種原因與 SP 本身相關聯,則可以使用它來填充臨時表,然后加入臨時表。 請注意,您將在那里花費一些額外的開銷,但這是我能想到的使用實際存儲過程的唯一方法。

同樣,最好將來自 SP 的查詢內聯到原始查詢中。

簡短的回答是“你不能”。 您需要做的是使用子查詢,或者您可以將現有的存儲過程轉換為表函數。 將其創建為函數將取決於您需要它的“可重用性”。

您的存儲過程可以輕松地用作視圖。 然后你可以將它加入到你需要的任何其他東西上。

查詢語句:

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

我解決了編寫函數而不是過程並在 SQL 語句中使用 CROSS APPLY 的問題。 此解決方案適用於 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 APPLYCROSS OUTER APPLY

這里閱讀。

干杯

我希望您的存儲過程沒有執行游標循環!

如果沒有,請從您的存儲過程中獲取查詢並將該查詢集成到您在此處發布的查詢中:

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

這是一個可怕的主意。

使用別名,從你的服務器創建一個新的鏈接服務器到它自己的別名。

現在你可以這樣做:

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

為什么不在您的 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