2010-10-28 11 views
0

Je souhaite avoir une construction dans une procédure stockée qui définit une table temporaire d'une manière dans une branche d'un if-else et d'une autre manière dans l'autre branche, mais cela ne compilera pas b/c il dit que la table est déjà créée. J'imagine quelque chose comme ce qui suit:déclaration de la table temporaire dans les deux branches d'un serveur SQL stocké conditionnel conditionnel

if 
begin 
    IF OBJECT_ID(N'tempdb..#tbl') IS NOT NULL DROP TABLE #tbl 
    create table #tbl (A int, B int) 
end 
else 
begin 
    IF OBJECT_ID(N'tempdb..#tbl') IS NOT NULL DROP TABLE #tbl 
    create table #tbl (A int, B int, C int) 
end 

qui semble devoir être bien défini.

Existe-t-il une meilleure façon de le faire que de le déclarer vide, puis de le modifier à plusieurs reprises pour ajouter les colonnes que je veux dans les branches? (C'est juste un peu moche)

+2

Je voudrais vraiment examiner pourquoi vous avez besoin de le faire du tout. –

+0

Je génère automatiquement des tableaux croisés dynamiques pour une page Web dont le nombre de colonnes varie en fonction des boutons qu'ils touchent. Pour ce faire sans dupliquer le code, j'utilise cette construction pour configurer la table de données de pivot –

+0

Pour les requêtes pivot, j'utilise généralement SQL dynamique pour construire une instruction en utilisant le mot clé PIVOT (2005 et ultérieur). Ceci est purement pour activer un nombre variable de colonnes, puisque le pivotement nécessite que vous spécifiez le nombre exact de colonnes. C'est dommage, mais c'est comme ça, et SQL dynamique fonctionne plutôt bien dans ce cas. – ulty4life

Répondre

0

Oui, apparemment, vous ne pouvez pas faire cela. J'ai appris quelque chose de nouveau aujourd'hui.

Il est un peu difficile de proposer une solution sans en savoir plus sur ce que vous devez faire, sur l'emplacement de votre clé primaire pour la table temporaire ou sur la logique conditionnelle.

Si vous ajoutez simplement des colonnes non-clés supplémentaires, vous pouvez utiliser une seule table temporaire avec les colonnes supplémentaires autorisant les valeurs nulles. Par la suite, vous pouvez utiliser ou non les colonnes supplémentaires, selon la même logique que celle utilisée pour remplir la table temporaire.

Si vous modifiez la clé primaire de la table, vous devez utiliser deux tables distinctes. En fonction de la logique de votre procédure, vous pouvez utiliser la syntaxe SELECT INTO pour créer la table temporaire en fonction du résultat de la requête.

Je ne l'ai pas essayé, mais vous pourriez probablement utiliser une instruction SQL dynamique pour créer la table. Je ne peux pas recommander de faire cela, sauf s'il n'y a pas d'autre solution.

+0

Le select into était une bonne idée, mais cela a généré la même erreur de compilateur à propos de l'impossibilité de créer une table qui existait déjà dans la branche else. En outre, il ne doit pas y avoir de clés sur cette table si cela aide. –

0

Exemple dynamique pivot sql:

CREATE PROCEDURE dbo.MyProc 
    @StartMonth   INT = 1 
    ,@StartYear   INT 
    ,@EndMonth   INT = 12 
    ,@EndYear   INT 
AS 
BEGIN 

    SET NOCOUNT ON 

    DECLARE @SQLString VARCHAR(MAX) 
    DECLARE @CalendarMonths VARCHAR(MAX) 
    SET @CalendarMonths = '' 

    IF @StartYear IS NULL 
     SET @StartYear = DATEPART(yyyy, getdate()) 

    IF @EndYear IS NULL 
     SET @EndYear = DATEPART(yyyy, getdate()) 

    DECLARE @YearCounter INT 
    DECLARE @MonthCounter INT 

    SET @YearCounter = @StartYear 
    SET @MonthCounter = @StartMonth 

    WHILE @YearCounter <= @EndYear 
    BEGIN 
     IF @YearCounter = @StartYear 
      SET @MonthCounter = @StartMonth 
     ELSE 
      SET @MonthCounter = 1 

     WHILE (@YearCounter = @EndYear AND @MonthCounter <= @EndMonth) OR (@YearCounter <> @EndYear AND @MonthCounter <= 12) 
     BEGIN 
      SET @CalendarMonths = @CalendarMonths + '[' + CAST(@MonthCounter AS VARCHAR) + '/' + CAST(@YearCounter AS VARCHAR) + '],' 
      SET @MonthCounter = @MonthCounter + 1 
     END 

     SET @YearCounter = @YearCounter + 1 
    END 

    SET @CalendarMonths = @CalendarMonths + ',@' -- add token to mark last ',' location 
    SET @CalendarMonths = REPLACE(@CalendarMonths, ',,@', '') -- remove last ',' 

    SET NOCOUNT OFF 


    SET @SQLString = 
' 
SELECT 
    * 
FROM 
(
    SELECT Units, CAST(CalendarMonth AS VARCHAR) + ''/'' + CAST(CalendarYear AS VARCHAR) AS Calendar, GroupID 
    FROM dbo.MyTable 
) ptg 
PIVOT 
(
    SUM(Units) 
    FOR Calendar IN 
    (
' 
     + CHAR(9) 
     + CHAR(9) 
     + @CalendarMonths + 
' 
    ) 
) pvt 
' 

    --PRINT(@SQLString) 
    EXEC(@SQLString) 

END 
GO