2013-10-14 4 views
0

je une procédure stockée avec parameter1 et parameter2procédure stockée SQL Server - refactorisation

intérieur de la procédure stockée, je crée une table temporaire

CREATE TABLE [dbo].#Temp  
(
[Item_ID] [int] NOT NULL, 
[Item] [nvarchar](255) NULL,  
[FIELD_1] [float] NULL, 
[FIELD_2] [float] NULL 

CONSTRAINT [PK___Temp] PRIMARY KEY CLUSTERED 
(
    [Item_ID] ASC 
) 

Insérez ensuite la valeur à la table temporaire.

INSERT INTO [dbo].#Temp(
    [Item_ID] 
    ,[Item] 
    ,[FIELD_1] 
    ,[FIELD_2] 
)SELECT DISTINCT 
      1 
      ,'Item Description' 
      ,(SELECT Field_Name FROM NewTable 
       WHERE Item_type = 'Middle' 
       AND param1 = @Parameter1 
       AND param2 = @Parameter2 
       AND STAFF_Type = 'Staff1' 
       AND Entity_Type = 'Entity1' 
      ) 

      ,(SELECT Field_Name FROM NewTable 
       WHERE Sch_type = 'High' 
       AND param1 = @Parameter1 
       AND param2 = @Parameter2 
       AND STAFF_Type = 'Staff1' 
       AND Entity_Type = 'Entity1' 
      ) 

INSERT INTO [dbo].#Temp(
    [Item_ID] 
    ,[Item] 
    ,[FIELD_1] 
    ,[FIELD_2] 
)SELECT DISTINCT 
      2 
      ,'Another Item Description' 
      ,(SELECT Field_Name FROM NewTable 
       WHERE Item_type = 'Middle' 
       AND param1 = @Parameter1 
       AND param2 = @Parameter2 
       AND STAFF_Type = 'Staff1' 
       AND Entity_Type = 'Entity2' 
      ) 

      ,(SELECT Field_Name FROM NewTable 
       WHERE Sch_type = 'High' 
       AND param1 = @Parameter1 
       AND param2 = @Parameter2 
       AND STAFF_Type = 'Staff1' 
       AND Entity_Type = 'Entity2' 
      ) 

ainsi de suite. Ensuite, sélectionnez la valeur de la table temporaire et déposez la table temporaire.

Je n'ai pas utilisé UDF et je me demande si cela pourrait être refactorisé pour être simple en utilisant UDF. tout exemple et/ou suggestion sont grandement appréciés.

Répondre

0

Nombre de voyages à la table sont importants à considérer. Par exemple, vous pouvez factoriser la requête existante pour réduire le nombre de voyages de 4 à 2:

INSERT INTO [dbo].#Temp(
    [Item_ID] 
    ,[Item] 
    ,[FIELD_1] 
    ,[FIELD_2] 
) 
     SELECT DISTINCT 
      1 AS Item_ID 
      ,'Item Description' AS Item 
      ,CASE WHEN Item_type = 'Middle' THEN Field_Name ELSE NULL END AS Field_1 
      ,CASE WHEN Sch_type = 'High' THEN Field_Name ELSE NULL END AS Field2 
     FROM NewTable 
     WHERE 
      param1 = @Parameter1 
      AND param2 = @Parameter2 
      AND STAFF_Type = 'Staff1' 
      AND Entity_Type = 'Entity1' 
     UNION 
     SELECT DISTINCT 
      2 AS Item_ID 
      ,'Another Item Description' AS Item 
      ,CASE WHEN Item_type = 'Middle' THEN Field_Name ELSE NULL END AS Field_1 
      ,CASE WHEN Sch_type = 'High' THEN Field_Name ELSE NULL END AS Field2 
     FROM NewTable 
     WHERE 
      param1 = @Parameter1 
      AND param2 = @Parameter2 
      AND STAFF_Type = 'Staff1' 
      AND Entity_Type = 'Entity2' 

Ou vous pouvez créer une fonction avec une logique similaire:

CREATE FUNCTION dbo.GetStaff1FieldNames (@param1 INT, @param2 INT, @Entity_Type VARCHAR(20)) 
RETURNS TABLE 
AS 
RETURN 

    SELECT 
     CASE WHEN Item_type = 'Middle' THEN Field_Name ELSE NULL END AS Field_1, 
     CASE WHEN Sch_type = 'High' THEN Field_Name ELSE NULL END AS Field_2 
    FROM NewTable 
    WHERE 
     param1 = @Parameter1 AND 
     param2 = @Parameter2 AND 
     Entity_Type = @Entity_Type AND 
     STAFF_Type = 'Staff1' 
    GO 

Ensuite, appelez comme ceci:

SELECT 
    1 
    ,'Item Description' 
    ,Field_1 
    ,Field_2 
FROM dbo.GetStaff1FieldNames (@param1, @param2, 'Entity1') 
UNION 
SELECT 
    2 
    ,'Another Item Description' 
    ,Field_1 
    ,Field_2 
FROM dbo.GetStaff1FieldNames (@param1, @param2, 'Entity2') 

Il y a peut-être des moyens de récupérer tout avec un voyage à la table, mais il me faudrait un peu plus de contexte sur les données à refactoriser plus loin.

0

Pourquoi ne pas utiliser un Common Table (or "WITH") Expression pour votre sélection? Ensuite, vous pouvez vous débarrasser de la table temporaire entièrement.

WITH Fields (ID, Desc, MidField, HighField) AS 
     (
     SELECT DISTINCT 
       1 
       , 'Item Description' 
       , (SELECT Field_Name FROM NewTable 
       WHERE Item_type = 'Middle' 
       AND param1 = @Parameter1 
       AND param2 = @Parameter2 
       AND STAFF_Type = 'Staff1' 
       AND Entity_Type = 'Entity1' 
       ) 
       , (SELECT Field_Name FROM NewTable 
       WHERE Sch_type = 'High' 
       AND param1 = @Parameter1 
       AND param2 = @Parameter2 
       AND STAFF_Type = 'Staff1' 
       AND Entity_Type = 'Entity1' 
       ) 
     UNION 
     SELECT DISTINCT 
       2 
       , 'Another Item Description' 
       , (SELECT Field_Name FROM NewTable 
       WHERE Item_type = 'Middle' 
       AND param1 = @Parameter1 
       AND param2 = @Parameter2 
       AND STAFF_Type = 'Staff1' 
       AND Entity_Type = 'Entity2' 
       ) 
       , (SELECT Field_Name FROM NewTable 
       WHERE Sch_type = 'High' 
       AND param1 = @Parameter1 
       AND param2 = @Parameter2 
       AND STAFF_Type = 'Staff1' 
       AND Entity_Type = 'Entity2' 
       ) 
    ) 
SELECT * 
FROM Fields 
WHERE MidField = 'XYZ' 

Notez que le CTE n'est disponible que pour la première instruction de sélection. Vous cannot perform multiple select statements against a CTE, bien que vous pouvez avez plusieurs CTE pour une seule instruction select:

WITH TempA (Columns) AS (SELECT * FROM TableA) 
    , TempB (Columns) AS (SELECT * FROM TableB) 
    , TempC (Columns) AS (SELECT * FROM TempA, TempB) 
SELECT * FROM TempC WHERE Columns = 1 
+0

Pourquoi diable les gens ne se tournent-ils pas vers les CTE face à un problème? Ils résolvent tellement. – ShellNinja