Comment utiliser une instruction CTE dans une fonction table dans SQL Server

J'ai fini par comprendre que certaines versions de Microsoft OLE DB Provider pour SQL Server (principalement sur Windows XP) ne prennent pas en charge l'instruction WITH . J'ai donc décidé de déplacer mon instruction SQL dans une fonction table et de l'appeler depuis mon application. Maintenant, je suis coincé. Comment dois-je utiliser l' INSERT INTO avec WITH ? Voici le code que je suis venu avec, mais SQL Server ne l'aime pas … 🙁

 CREATE FUNCTION GetDissortingbutionTable ( @IntID int, @TestID int, @DateFrom datetime, @DateTo datetime ) RETURNS @Table_Var TABLE ( [Count] int, Result float ) AS BEGIN INSERT INTO @Table_Var ([Count], Result) WITH T(Result) AS (SELECT ROUND(Result - AVG(Result) OVER(), 1) FROM RawResults WHERE IntID = @IntID AND DBTestID = @TestID AND Time >= @DateFrom AND Time <= @DateTo) SELECT COUNT(*) AS [Count], Result FROM T GROUP BY Result RETURN END GO 

Vous pouvez omettre l'instruction CTE ( WITH ) et créer à la place une fonction de valeur de table en ligne qui utilise la sous-requête:

 CREATE FUNCTION GetDissortingbutionTable ( @IntID int, @TestID int, @DateFrom datetime, @DateTo datetime ) RETURNS TABLE AS RETURN ( SELECT COUNT(*) AS [Count], Result FROM ( SELECT ROUND(Result - AVG(Result) OVER(), 1) Result FROM RawResults WHERE IntID = @IntID AND DBTestID = @TestID AND Time >= @DateFrom AND Time <= @DateTo ) t GROUP BY Result ) GO 

La syntaxe pour le CTE dans la fonction de valeur de table serait:

 CREATE FUNCTION GetDissortingbutionTable ( @IntID int, @TestID int, @DateFrom datetime, @DateTo datetime ) RETURNS TABLE AS RETURN ( WITH cte AS ( SELECT ROUND(Result - AVG(Result) OVER(), 1) Result FROM RawResults WHERE IntID = @IntID AND DBTestID = @TestID AND Time >= @DateFrom AND Time <= @DateTo ) SELECT COUNT(*) AS [Count], Result FROM cte GROUP BY Result ) GO 

Votre exemple semble utiliser un TVF multi-instructions (insert et sélectionner), lorsque vous avez le choix d'utiliser le TVF en ligne parce que le TVF multi-instructions peut empêcher l'optimiseur de requêtes en choisissant un meilleur plan d'exécution (différence de performance expliquée ici )

COMME ÇA..

 CREATE FUNCTION GetDissortingbutionTable ( @IntID int, @TestID int, @DateFrom datetime, @DateTo datetime ) RETURNS @Table_Var TABLE ( [Count] int, Result float ) AS BEGIN WITH T AS ( select Ticket_Id,COUNT(1) Result from Customer_Survey group by MemberID,SiteId,Ticket_Id ) INSERT INTO @Table_Var ([Count], Result) SELECT COUNT(*) AS [Count], Result FROM T GROUP BY Result RETURN END GO