Afficher la jointure avec les résultats de la procédure stockée

J'ai une vue existante dans le server SQL utilisé par l'application. Je dois joindre à la table returnnée de la procédure stockée. La procédure stockée fait beaucoup de choses comme l'insertion dans plusieurs tables #temp avant de renvoyer le résultat.

J'ai essayé de convertir la procédure stockée en fonction Table valorisée. Mais l'insertion dans la table temporaire à l'intérieur du TVF provoque une erreur de compilation.

Y a-t-il un autre moyen d'y parvenir?

Merci

Vous pouvez insert les résultats de la procédure stockée dans une table temporaire, puis l'associer à la vue.

Jetez un oeil à l'exemple ci-dessous

SQL Fiddle DEMO

 CREATE TABLE TADA( ID INT ); INSERT INTO TADA VALUES (1),(2); CREATE VIEW vw_TADA AS SELECT * FROM TADA WHERE ID <= 1; CREATE PROCEDURE sp_TADA AS SELECT * FROM TADA WHERE ID > 1; CREATE TABLE #TADA( ID INT ) INSERT INTO #TADA EXEC sp_TADA SELECT * FROM vw_TADA UNION ALL SELECT * FROM #TADA 

Une autre astuce consiste à utiliser OPENQUERY . De ma réponse ici :

Il nécessite l'utilisation de OPENQUERY et d'un server lié en boucle avec la propriété 'DATA ACCESS' définie sur true. Vous pouvez vérifier sys.servers pour voir si vous avez déjà un server valide, mais créons juste un loopback appelé manuellement:

 EXEC master..sp_addlinkedserver @server = 'loopback', @srvproduct = '', @provider = 'SQLNCLI', @datasrc = @@SERVERNAME; EXEC master..sp_serveroption @server = 'loopback', @optname = 'DATA ACCESS', @optvalue = 'TRUE'; 

Maintenant que vous pouvez interroger cela en tant que server lié, vous pouvez utiliser le résultat de n'importe quelle requête (y compris un appel de procédure stockée) en tant que SELECT standard. Vous pouvez donc le faire (notez que le préfixe de database est important, sinon vous obtiendrez l'erreur 11529 et 2812):

 SELECT * FROM OPENQUERY(loopback, 'EXEC db.dbo.procedure;') AS x; 

Maintenant, vous pouvez join votre vue.

Mais honnêtement, je pense qu'il vaudrait mieux réécrire la procédure en tant que TVF et cesser d'utiliser les tables #temp dans la logique. Ce qui précède pourrait fonctionner sur votre instance actuelle, mais cela ne fonctionnera pas dans SQL Server 2012 (les métadonnées ne peuvent pas être déterminées à cause de la table #temp dans la procédure) et cela ne fonctionnera pas si vous avez une certaine database ou server DDL triggersurs de niveau soit (pour le même type de raison).

Voir aussi http://www.sommarskog.se/share_data.html#OPENQUERY pour d'autres informations et limitations.

Juste pour append une autre méthode pour traiter une telle donnée, vous pouvez utiliser la table temporaire partagée ou le paramètre output xml pour get des données de la procédure stockée. En fait, il nécessite de modifier votre procédure, de sorte qu'il pourrait ne pas être une option. Le conseil général est d'essayer de réécrire votre procédure dans la fonction de table (vous pouvez changer les tables temporaires en variables de table)

paramètre xml

 CREATE PROCEDURE sp_Process2 ( @Data xml = null output, @Fill_Data bit = 0 ) AS begin create table #Test1 (ID int, Name nvarchar(128), Col3 nvarchar(128)) -- do some work insert into #Test1 select 1, 'From Procedure', 'Unused' if @Fill_Data = 1 -- put data into xml parameter begin select @Data = ( select * from #Test1 for xml raw('Data') ) end else -- just return recordset begin select * from #Test1 end end; 

table partagée (SQL dynamic est complètement facultatif, juste pour passer le nom de la table et les colonnes dans la procédure)

 CREATE PROCEDURE sp_Process ( @Table_Name nvarchar(128) = null, @Columns nvarchar(max) = null ) AS begin declare @stmt nvarchar(max) create table #Test1 (ID int, Name nvarchar(128), Col3 nvarchar(128)) -- do some work insert into #Test1 select 1, 'From Procedure', 'Unused' if @Table_Name is not null -- put data into temporary table begin select @stmt = 'insert into ' + quotename(@Table_Name) + ' select ' + @Columns + ' from #Test1' exec sp_executesql @stmt = @stmt end else -- just return recordset begin select * from #Test1 end end; 

voir sql violon avec des exemples