web-dev-qa-db-ja.com

ストアドプロシージャに参加するにはどうすればよいですか?

パラメータを取らないストアドプロシージャがあり、2つのフィールドを返します。ストアドプロシージャは、テナントに適用されるすべてのトランザクションを合計し、テナントの残高と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

ストアドプロシージャの残高も追加したいと思います。

これどうやってするの?

43
Malfist

私は実際には前の回答が好きです(SPを使用しないでください)が、何らかの理由でSP自体に縛られている場合は、それを使用して一時テーブルを作成し、一時テーブルに参加します。追加のオーバーヘッドが発生することに注意してくださいが、実際のストアドプロシージャを使用する唯一の方法です。

繰り返しますが、クエリをSPから元のクエリにインライン化する方が良いかもしれません。

25
AllenG

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

短い答えは「できません」です。必要なことは、サブクエリを使用するか、既存のストアドプロシージャをテーブル関数に変換することです。関数として作成するかどうかは、必要な「再利用可能性」に依存します。

18
CAbbott

代わりに、ストアドプロシージャをビューとして簡単に使用できます。その後、必要なものに参加できます。

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
9
cjk

プロシージャの代わりに関数を記述し、SQLステートメントでCROSS APPLYを使用して、この問題を解決しました。このソリューションは、SQL 2005以降のバージョンで機能します。

ゲディミナスブカウスカス

6

既に回答済みです。回避策として最適なのは、ストアドプロシージャを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を使用することをお勧めします。

here を読んでください。

乾杯

5
Fandango68

ストアドプロシージャがカーソルループを実行していないことを願っています。

そうでない場合は、ストアドプロシージャからクエリを取得し、ここに投稿するクエリ内にそのクエリを統合します。

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

これはあなたのためのひどいアイデアです。

エイリアスを使用して、サーバーから独自のエイリアスへの新しいリンクサーバーを作成します。

できるようになりました:

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
0
Devin Lamothe

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
0