web-dev-qa-db-ja.com

SQL Server - ストアドプロシージャからのSELECT

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

CREATE PROCEDURE MyProc
AS
BEGIN
    SELECT * FROM MyTable
END

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

この手続きを呼び出して出力を選択することは可能ですか?

何かのようなもの:

SELECT * FROM (EXEC MyProc) AS TEMP

データをページングするためにSELECT TOP XROW_NUMBER、および追加のWHERE句を使用する必要があります。これらの値をパラメータとして渡したくはありません。

287
jonathanpeppers

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

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

134
Mehrdad Afshari

あなたはできる

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

... SQL ...

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

Erland Sommarskogによるこの素晴らしい記事を見てください。

それは基本的にあなたのシナリオに利用可能なすべてのオプションをリストします。

148
kristof

テーブル値関数 またはEXECを一時テーブルに挿入します。

INSERT INTO #tab EXEC MyProc
69
CMerat

_ openrowset _ および _ openquery _ について読んでください。

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

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

これが私の解決策です

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

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

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

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

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

最後にあなたのテーブルタイプから選択してください

Select * from @MyTableType
30
Aamir

Spから一時テーブルに出力をコピーできます。

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
23
_Seba_

oPENQUERYを使用して、set 'SET FMTONLY OFFを実行してください。 NOCOUNTをONに設定します。

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

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

あなたの手続きを次のようにテーブルを返すインライン関数に変換してみてください。

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 )
5
al_the_man

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

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

もちろんこれは毎回SP全体を実行します。

5
MartW

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

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

後、

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

できます。

5
Ali Osman Yavuz

簡単にするために、そして再実行可能にするために、データを取得するためにシステム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
4
Sheikh Kawser

view を使う必要があるかもしれません。ビューを使用すると、クエリをテーブルとして表すことができるので、ビュー、つまりクエリを実行できます。

2

あなたのサーバーが例えば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に置き換えてコマンドを確認してから実行しようとしました。これは、正しい数の単一引用符がすべて正しい位置にあることを確認するためでした。 :-)

それが誰かに役立つことを願っています。

1
Fandango68