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.
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
.
Vous pouvez
... sql ....
Declare @T Table ([column definitions here])
Insert @T Exec storedProcname params
Select * from @T Where ...
Vous devriez consulter cet excellent article d'Erland Sommarskog:
Il répertorie essentiellement toutes les options disponibles pour votre scénario.
Vous voulez soit une fonction Table-Valued ou insérer votre EXEC dans une table temporaire:
INSERT INTO #tab EXEC MyProc
Vous devez lire à propos de OPENROWSET et OPENQUERY
SELECT *
INTO #tmp FROM
OPENQUERY(YOURSERVERNAME, 'EXEC MyProc @parameters')
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
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
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
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 ')
Si 'DATA ACCESS' est faux,
EXEC sp_serveroption 'SQLSERVERNAME', 'DATA ACCESS', TRUE
après,
SELECT * FROM OPENQUERY(SQLSERVERNAME, 'EXEC DBNAME..MyProc @parameters')
ça marche.
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 )
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.
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
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.
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.