web-dev-qa-db-fra.com

SQL Server - SELECT FROM procédure stockée

J'ai une procédure stockée qui retourne des lignes:

CREATE PROCEDURE MyProc
AS
BEGIN
    SELECT * FROM MyTable
END

Ma procédure actuelle est un peu plus compliquée, c'est pourquoi un sproc est nécessaire.

Est-il possible de sélectionner la sortie en appelant cette procédure?

Quelque chose comme:

SELECT * FROM (EXEC MyProc) AS TEMP

Je dois utiliser SELECT TOP X, ROW_NUMBER et une clause WHERE supplémentaire pour la mise en page de mes données et je ne souhaite pas vraiment passer ces valeurs en tant que paramètres.

290
jonathanpeppers

Vous pouvez utiliser une fonction définie par l'utilisateur ou une vue à la place d'une procédure.

Une procédure peut renvoyer plusieurs jeux de résultats, chacun avec son propre schéma. Il n'est pas approprié d'utiliser dans une instruction SELECT.

136
Mehrdad Afshari

Vous pouvez

  1. créer une variable de table pour contenir l'ensemble de résultats à partir du proc stocké, puis
  2. insérer la sortie du proc stocké dans la variable de table, puis
  3. utilisez la variable de table exactement comme n'importe quelle autre table ...

... sql ....

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

Vous devriez consulter cet excellent article d'Erland Sommarskog:

Il répertorie essentiellement toutes les options disponibles pour votre scénario.

149
kristof

Vous voulez soit une fonction Table-Valued ou insérer votre EXEC dans une table temporaire:

INSERT INTO #tab EXEC MyProc
69
CMerat

Vous devez lire à propos de OPENROWSET et OPENQUERY

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

Vous devez déclarer un type de table contenant le même nombre de colonnes renvoyées par votre procédure de magasin. Les types de données des colonnes du type de table et les colonnes renvoyées par les procédures doivent être identiques

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

Ensuite, vous devez insérer le résultat de votre procédure stockée dans le type de table que vous venez de définir.

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

À la fin, il suffit de sélectionner votre type de table

Select * from @MyTableType
32
Aamir

Il n'est pas nécessaire d'utiliser une table temporaire.

C'est ma solution

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

Vous pouvez copier la sortie de sp dans une table temporaire.

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_

utilisez OPENQUERY et befor Execute set 'SET FMTONLY OFF; SET NOCOUNT ON; '

Essayez cet exemple de code:

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

Si 'DATA ACCESS' est faux,

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

après,

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

ça marche.

6
Ali Osman Yavuz

Essayez de convertir votre procédure en une fonction en ligne qui renvoie un tableau comme suit:

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

Et puis vous pouvez l'appeler comme

SELECT * FROM MyProc()

Vous avez également la possibilité de transmettre des paramètres à la fonction comme suit:

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

Et appelle ça

SELECT * FROM FuncName ( @para1 , @para2 )
5
al_the_man

Vous pouvez tricher un peu avec OPENROWSET:

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

Ceci exécuterait toujours le SP entier à chaque fois, bien sûr.

5
MartW

Par souci de simplicité et pour le rendre ré-exécutable, j'ai utilisé un système StoredProcedure "sp_readerrorlog" pour obtenir des données:

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

Il semble que vous ayez simplement besoin d'utiliser view . Une vue permet à une requête d'être représentée sous forme de table afin que la vue puisse être interrogée.

2
Lawrence Barsanti

Si votre serveur s'appelle SERVERX par exemple, voici comment je l'ai fait ...

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);

Pour vérifier si cela fonctionnait, j'ai commenté la ligne de commande EXEC() et l'ai remplacée par SELECT @CMD afin de vérifier la commande avant d'essayer de l'exécuter! C'était pour s'assurer que tout le nombre correct de guillemets simples était au bon endroit. :-)

J'espère que cela aide quelqu'un.

1
Fandango68