SQL Server-SELECT FROMストアドプロシージャ


333

行を返すストアドプロシージャがあります。

CREATE PROCEDURE MyProc
AS
BEGIN
    SELECT * FROM MyTable
END

実際の手順はもう少し複雑なので、sprocが必要です。

このプロシージャを呼び出すことによって出力を選択することは可能ですか?

何かのようなもの:

SELECT * FROM (EXEC MyProc) AS TEMP

私が使用する必要があるSELECT TOP XROW_NUMBERと、追加のWHEREページへの句自分のデータ、と私は本当にパラメータとして、これらの値を渡す必要はありません。


ここで何をするつもりなのかはわかりませんが、プロシージャを実行すると、行が返されます。ページング可能なオブジェクトに関連付けることができるように、SELECTステートメント内でプロシージャを実行したいですか?
Raj More

1
値をパラメーターとして渡したくない特別な理由はありますか?あなたが提案している方法でそれを行うことは少し非能率的です-必要以上のデータを選択し、それをすべて使用することはないでしょう。
Mark Bell、

2
こちらをご覧ください:sommarskog.se/share_data.html
pylover

回答:


149

プロシージャの代わりに、ユーザー定義関数またはビューを使用できます。

プロシージャは、それぞれ独自のスキーマを持つ複数の結果セットを返すことができます。SELECTステートメントでの使用には適していません。


8
さらに、UDFへの変換後にストアドプロシージャのセマンティクスが必要であることがわかった場合は、常にUDFをプロシージャでラップできます。
Joel Coehoorn、2009

パラメータを複数のストアドプロシージャに送信し、それらを1つの大きなストアドプロシージャに結合する必要がある場合はどうなるでしょうか。ストアドプロシージャと同様に、パラメーターを表示、取得できます
mrN '18

3
@mrNビューはパラメーターを受け取りませんが、UDFは受け取ります。
Mehrdad Afshari、2011

3
こんにちは、spをビューまたは関数に変換せずに本当にこれを行う必要があります。それは可能ですか?
Luis Becerril 2017年

2
あなたの答えは本当のステートメントですが、質問には答えません....「SELECT FROMストアドプロシージャ」確かに理想的ではありませんが、それはそれです... @Aamirの答えは正しい答えです。それか質問を変更する必要があります...私には少しばかげているようです。
Urasquirrel

201

あなたはできる

  1. ストアドプロシージャからの結果セットを保持するテーブル変数を作成し、次に
  2. ストアドプロシージャの出力をテーブル変数に挿入し、次に
  3. 他のテーブルとまったく同じようにテーブル変数を使用します...

... sql ....

Declare @T Table ([column definitions here])
Insert @T Exec storedProcname params 
Select * from @T Where ...

34
INSERT #Tまたはの問題INSERT @Tは、INSERT EXECステートメントをネストできないことです。ストアドプロシージャに既にがあるINSERT EXEC場合、これは機能しません。
MOHCTP 2013年

2
これはおそらく最もポータブルなソリューションであり、基本的なSQLに最も近いものです。また、強力な列タイプ定義の維持にも役立ちます。上記よりも多くの賛成票が必要です。

ここでは、テーブル変数は一時テーブルよりもsp再コンパイルの点でより便利に見えます。したがって、私は同意します。この回答にはもっと賛成票があるはずです。
resnyanskiy 2016年

76

あなたはどちらかしたいテーブル値関数をまたは一時テーブルにあなたのEXECを挿入します。

INSERT INTO #tab EXEC MyProc

31
INSERT #Tまたはの問題INSERT @Tは、INSERT EXECステートメントをネストできないことです。ストアドプロシージャに既にがあるINSERT EXEC場合、これは機能しません。
MOHCTP 2013年

46

OPENROWSETOPENQUERYについて読む必要があります

SELECT  * 
INTO    #tmp FROM    
OPENQUERY(YOURSERVERNAME, 'EXEC MyProc @parameters')

4
YOURSERVERNAMEを動的に取得する方法?あなたはいつも知る必要があると期待することはできません。隔週の火曜日にこれは休憩しませんか?したがって、100台のサーバーにすべて異なる名前が付いている場合...
Urasquirrel

また、私のデータベースがこれを許可するように構成されていない場合はどうなりますか?
Urasquirrel

4
@@ servernameを試して動的に取得してください
Siddhartha Gandhi

44

ストアプロシージャが返す列と同じ数の列を含むテーブル型を宣言する必要があります。テーブル型の列のデータ型とプロシージャによって返される列は同じである必要があります

declare @MyTableType as table
(
FIRSTCOLUMN int
,.....
)  

次に、定義したテーブルタイプにストアドプロシージャの結果を挿入する必要があります。

Insert into @MyTableType 
EXEC [dbo].[MyStoredProcedure]

最後に、テーブルタイプから選択します

Select * from @MyTableType

サーバー名、接続文字列を指定したり、リンクサーバーを構成したりして機能させる必要がないため、これが私にとって最良のソリューションです。一部のデータが戻ってきました。ありがとうございました!すばらしい回答です。
Matt

ニースの答えღ❤ೋღ❤ღೋ❤ღ
Nahid

ストアドプロシージャが難しすぎる場合-たとえば、ストアドプロシージャが2つの一時テーブルを使用する場合、この方法は機能しません。
nick_n_a

34

一時テーブルを使用する必要はありません。

これは私の解決策です

SELECT  *  FROM    
OPENQUERY(YOURSERVERNAME, 'EXEC MyProc @parameters')
WHERE somefield = anyvalue

2
これには、サーバーをリンクサーバーとしてそれ自体に追加する必要がありますが、それは魅力のように機能します!ありがとう!
vaheeds

この上でいくつかの偉大な注意点:stackoverflow.com/questions/2374741/...
キース・アドラー

1
うーん...「エラー7411:サーバー 'YourServerName'はデータアクセス用に構成されていません。」というエラーが表示されます。何を変更する必要がありますか?
Matt

サーバーをリンクサーバーとして追加しましたか?YourServerNameはサーバーの名前です。YourServerNameを実際のサーバー名に変更する必要があります。
DavideDM 2017

@マット:sp_serveroption 'MYSERVER', 'DATA ACCESS', TRUE;
alexkovelsky 2018

23

出力をspからtemporatyテーブルにコピーできます。

CREATE TABLE #GetVersionValues
(
    [Index] int,
    [Name]  sysname,
    Internal_value  int,
    Character_Value sysname
)
INSERT #GetVersionValues EXEC master.dbo.xp_msver 'WindowsVersion'
SELECT * FROM #GetVersionValues
drop TABLE #GetVersionValues

7

OPENQUERYを使用し、実行セットの前に 'SET FMTONLY OFF; NOCOUNTをオンに設定してください。 '

次のサンプルコードを試してください。

SELECT top(1)*
FROM
OPENQUERY( [Server], 'SET FMTONLY OFF; SET NOCOUNT ON; EXECUTE  [database].[dbo].[storedprocedure]  value,value ')

6

プロシージャを次のようにテーブルを返すインライン関数に変換してみてください。

CREATE FUNCTION MyProc()
RETURNS TABLE AS
RETURN (SELECT * FROM MyTable)

そして、あなたはそれを次のように呼ぶことができます

SELECT * FROM MyProc()

次のように、関数にパラメーターを渡すオプションもあります。

CREATE FUNCTION FuncName (@para1 para1_type, @para2 para2_type , ... ) 

そしてそれを呼ぶ

SELECT * FROM FuncName ( @para1 , @para2 )

6

「データアクセス」が偽の場合、

EXEC sp_serveroption 'SQLSERVERNAME', 'DATA ACCESS', TRUE

あと、

SELECT  *  FROM OPENQUERY(SQLSERVERNAME, 'EXEC DBNAME..MyProc @parameters')

できます。


5

OPENROWSETで少しカンニングすることができます:

SELECT ...fieldlist...
FROM OPENROWSET('SQLNCLI', 'connection string', 'name of sp')
WHERE ...

もちろん、これでも毎回SP全体が実行されます。


4

簡単にするため、および再実行可能にするために、システムStoredProcedure "sp_readerrorlog"を使用してデータを取得しました。

-----USING Table Variable
DECLARE @tblVar TABLE (
   LogDate DATETIME,
   ProcessInfo NVARCHAR(MAX),
   [Text] NVARCHAR(MAX)
)
INSERT INTO @tblVar Exec sp_readerrorlog
SELECT LogDate as DateOccured, ProcessInfo as pInfo, [Text] as Message FROM @tblVar



-----(OR): Using Temp Table
IF OBJECT_ID('tempdb..#temp') IS NOT NULL  DROP TABLE #temp;
CREATE TABLE #temp (
   LogDate DATETIME,
   ProcessInfo NVARCHAR(55),
   Text NVARCHAR(MAX)
)
INSERT INTO #temp EXEC sp_readerrorlog
SELECT * FROM #temp


1

たとえば、サーバーがSERVERXと呼ばれている場合、これは私がやった方法です...

EXEC sp_serveroption 'SERVERX', 'DATA ACCESS', TRUE;
DECLARE @CMD VARCHAR(1000);
DECLARE @StudentID CHAR(10);
SET @StudentID = 'STUDENT01';
SET @CMD = 'SELECT * FROM OPENQUERY([SERVERX], ''SET FMTONLY OFF; SET NOCOUNT ON; EXECUTE MYDATABASE.dbo.MYSTOREDPROC ' + @StudentID + ''') WHERE SOMEFIELD = SOMEVALUE';
EXEC (@CMD);

これが機能していることを確認するために、EXEC()コマンドラインをコメントアウトして置き換えSELECT @CMD、実行前にコマンドを確認しました。これは、正しい数の単一引用符がすべて正しい場所にあることを確認するためです。:-)

私はそれが誰かを助けることを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.