web-dev-qa-db-fra.com

Impossible d'accéder aux tables temporaires depuis une fonction

Je voudrais obtenir le compte de disques spécifiques. Donc, ma requête ressemblera à ce qui suit ...

SELECT
    ID, 
    NAME,
    (SELECT...) AS UserCount // Stmt1
FROM MyTable

Le problème est que 'Stmt1' est une déclaration complexe et qu'il ne peut pas être écrit comme une requête interne. Je peux utiliser des fonctions, mais l'instruction inclut 'CREATE TABLE', le message d'erreur suivant s'affiche.

Cannot access temporary tables from within a function.

Quelle est la meilleure façon d'accomplir la tâche?

14
Rauf

Vous pouvez utiliser le type de table défini par l'utilisateur pour résoudre votre problème.

Vous venez de créer une variable de table comme

CREATE TYPE [dbo].[yourTypeName] AS TABLE(
    [columeName1] [int] NULL,
    [columeName2] [varchar](500) NULL,
    [columeName3] [varchar](1000) NULL
)
GO

et vous pouvez déclarer cette variable de table dans votre fonction comme

    CREATE FUNCTION [dbo].[yourFunctionName] 
( 
    @fnVariable1 INT ,
    @yourTypeNameVariable yourTypeName READONLY
) 
RETURNS VARCHAR(8000) 
AS 
BEGIN 

    SELECT .................
        FROM @yourTypeNameVariable 
        WHERE ........
    RETURN @r 
END 

Sur votre procédure, vous pouvez déclarer votre type de table comme

DECLARE @yourTypeNamevaribale AS yourTypeName 

Et vous pouvez insérer des valeurs dans cette table comme 

insert into @yourTypeNamevaribale (col,col,..)values(val,val,..)

passe ceci à ta fonction comme

dbo.yourFunctionName(fnVariable1 ,@yourTypeNamevaribale )

s'il vous plaît aller pour cette méthode, merci

21

Oui, vous ne pouvez pas utiliser la table #temp.

Puisque vous utilisez SQL Server 2008, pourquoi n’utilisez-vous pas la variable de table au lieu de #temp tables? Essayez-le.

2
Rajan

Je suis tombé sur ce billet lorsque j'ai commencé à utiliser des variables de table et que je suis passé à des tables temporaires pour des raisons de performances, mais que seules des tables temporaires ne pouvaient pas être utilisées dans une fonction.

J’aimerais hésiter à utiliser des variables de table, en particulier si vous jouez avec des ensembles de résultats volumineux, car ceux-ci sont conservés en mémoire. Voir ce post ...

http://totogamboa.com/2010/12/03/speed-matters-subquery-vs-table-variable-vs-temporary-table/

D'autres alternatives seraient ..

  1. Extraire le résultat de la table temporaire dans une autre fonction de table. 
  2. Conversion du code en utilisant des sous-requêtes
1
Mick

Dans 99,99% des cas, aucune astuce n'est requise avec des tables temporaires ou des sous-requêtes, mais utilisez des fonctions d'agrégation telles que COUNT, SUM ou AVG en combinaison avec OVER clause et (souvent) PARTITION BY.

Je ne suis pas sûr de ce que le PO a tenté de réaliser, mais je suppose que UserCount est en quelque sorte lié aux valeurs de MyTable. Il doit donc y avoir un moyen de joindre MyTable à la table qui produit UserCount

L’exemple le plus simple consiste à afficher tous les utilisateurs et le nombre total d’utilisateurs.

SELECT id
    , name
    , user_count = COUNT(*) OVER()
FROM MyUsers
0
Konstantin