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