2013-10-14 3 views
0

У меня есть хранимая процедура с parameter1 и parameter2SQL Server хранимые процедуры - рефакторинга

Внутри хранимой процедуры, я создаю временную таблицу

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 
) 

Затем вставить значение в временную таблицу.

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' 
      ) 

и др. И т. Д. Затем выберите значение из таблицы temp и отпустите таблицу temp.

Я не использовал UDF и задавался вопросом, может ли это быть реорганизованным, чтобы быть простым с использованием UDF. любой пример и/или предложения приветствуются.

ответ

0

Количество поездок в таблице важно учитывать. Например, вы можете реорганизовать существующий запрос, чтобы уменьшить количество поездок от 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' 

Или вы могли бы создать функцию с подобной логикой:

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 

Тогда называем это следующим образом:

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') 

Есть, возможно, способов извлечь все с одной поездки в таблице, но я должен был бы больше некоторый контекст о данных реорганизовать дальше.

0

Почему бы не использовать Common Table (or "WITH") Expression для вашего выбора? Тогда вы можете полностью избавиться от временной таблицы.

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' 

Обратите внимание, что CTE доступен только для первого оператора выбора. Вы cannot perform multiple select statements against a CTE, хотя вы можете иметь несколько CTE для одного оператора выбора:

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

Почему люди не обращаются к CTE, когда сталкиваются с проблемой? Они так решают. – ShellNinja

Смежные вопросы