2014-09-06 45 views
1

這是一個相當溫和的問題,但是如何創建一個用戶定義函數的SQL服務器

我有我試圖簡化可讀性相當大的存儲過程

它包含了許多union子句與像下面圖1所示

圖1的一個聲明

SELECT COUNT(1) AS Total 
    FROM Orders 
    WHERE (NOT EXISTS (
     SELECT 1 
     FROM (
      SELECT Id 
      FROM OrderLineItems 
      WHERE Orders.Id = Order_Id) AS Sub 
     WHERE EXISTS (
      SELECT 1 
       FROM NormalizedLineItems 
       WHERE (Sub.Id = OrderLineItem_Id) 
       AND (OutOfStock = 1)))) 
    AND (EXISTS (
     SELECT 1 AS Total 
     FROM OrderShipments 
     WHERE (Orders.Id = Order_Id) 
      AND (CarrierApproved = 0))) 
    AND (IsQuote = 0) 
    AND (Cancelled = 0) 
    AND (Archived = 0) 
    AND (Completed = 0) 
    AND (Holding = 0) 

但是也有很多REOC curring圖案在每個語句

以下圖案變成了幾次圖2

圖2

WHERE (NOT EXISTS (
     SELECT 1 
     FROM (
      SELECT Id 
      FROM OrderLineItems 
      WHERE Orders.Id = Order_Id) AS Sub 
     WHERE EXISTS (
      SELECT 1 
       FROM NormalizedLineItems 
       WHERE (Sub.Id = OrderLineItem_Id) 
       AND (OutOfStock = 1)))) 

進出口試圖(出於可讀性目的)減少在存儲在主代碼程序

所以我認爲ID性能測試的UDF,我想出了以下圖3

圖3

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

CREATE FUNCTION TestFunction (@OrderId int) 
RETURNS TABLE 
AS 
    RETURN 
    (
    -- Add the SELECT statement with parameter references here 
    SELECT 1 AS Total 
    FROM (
     SELECT OrderLineItems.Id AS Id 
     FROM OrderLineItems 
     WHERE @OrderId = Order_Id) AS Sub 
    WHERE EXISTS (
     SELECT 1 AS Total 
      FROM NormalizedLineItems 
      WHERE (Sub.Id = OrderLineItem_Id) 
      AND (OutOfStock = 1))) 
GO 

所有雖然上述編譯,我真的不知道我在正確的軌道上,我遇到各種各樣的問題試圖上述UDF向原查詢

我在想,如果有人可以給我從圖1如何抽象圖2的具體例子爲UDF這樣我就可以至少性能測試解決方案,看看它的價值,而

注:我知道用戶定義的功能可能是一場性能噩夢,但即使我不能在一個階段,我也不會

SELECT COUNT(1) AS Total 
    FROM Orders 
    join order_ids 
    on order_ids.order_id = Orders.order_id 
... 

如果再次發生語句只在一個:EST

感謝

+0

這可能是使用UDF簡化where子句中的代碼的最後一個選擇。使用CTE或常規表格進行可重用數據是一種很好的做法。或者'EXEC'動態查詢由不同的sql語句字符串組合而成。 – 2014-09-06 02:51:24

+0

感謝您的意見和回答,對您提出的觀點進行了不恰當的研究,並測試了您的代碼,爲我提供了深思熟慮的內容 – 2014-09-06 02:55:25

回答

1

只名爲ORDER_ID

Insert into order_ids 
select order_id from 
    FROM Orders 
    WHERE (NOT EXISTS (
     SELECT 1 
     FROM (
      SELECT Id 
      FROM OrderLineItems 
      WHERE Orders.Id = Order_Id) AS Sub 
     WHERE EXISTS (
      SELECT 1 
       FROM NormalizedLineItems 
       WHERE (Sub.Id = OrderLineItem_Id) 
       AND (OutOfStock = 1)))) 

然後你就可以簡化您的SQL像這樣的列上創建order_ids表查詢, Common Table Expression是最佳選擇:

with CTE_order_ids as 
(select order_id from 
    FROM Orders 
    WHERE (NOT EXISTS (
     SELECT 1 
     FROM (
      SELECT Id 
      FROM OrderLineItems 
      WHERE Orders.Id = Order_Id) AS Sub 
     WHERE EXISTS (
      SELECT 1 
       FROM NormalizedLineItems 
       WHERE (Sub.Id = OrderLineItem_Id) 
       AND (OutOfStock = 1)))) 
) 
SELECT COUNT(1) AS Total 
    FROM Orders 
    join CTE_order_ids 
    on order_ids.order_id = Orders.order_id 
... 
+0

感謝您的支持,我對它進行了測試,並且還給了我一個很好的性能優勢 – 2014-09-06 05:05:00

相關問題