2015-10-02 68 views
1

我有以下(簡化的)存儲過程:添加列到存儲過程有條件

CREATE FUNCTION [dbo].[UDF_FulfilmentBatch](@FulfilmentID INT) RETURNS 
    @Result TABLE (
      [sequence] INT, 
      membershipid BIGINT, 
      membershipNo VARCHAR(255) 
    ) 
    AS 
    BEGIN 

    DECLARE @_sequence INT 
    DECLARE @_membershipid BIGINT 
    DECLARE @_membershipNo VARCHAR(255) 

    SET @_sequence = 1 

    IF @FulfilmentID = 4 
    BEGIN 
     DECLARE FulfilCursor CURSOR FAST_FORWARD FOR 
      SELECT * from VW_FulfilmentExtract_HH 
    END 
IF @FulfilmentID = 3 
    BEGIN 
     DECLARE FulfilCursor CURSOR FAST_FORWARD FOR 
      SELECT * from VW_FulfilmentExtract_ID 
    END 
    ELSE IF @FulfilmentID = 2 
    BEGIN 
     DECLARE FulfilCursor CURSOR FAST_FORWARD FOR 
      SELECT * from VW_FulfilmentExtract_Art 
    END 
    ELSE 
     DECLARE FulfilCursor CURSOR FAST_FORWARD FOR 
      SELECT * from VW_FulfilmentExtract_Tha 

    OPEN FulfilCursor 

    FETCH NEXT FROM FulfilCursor INTO @_membershipid, @_membershipNo 

    WHILE @@FETCH_STATUS = 0 BEGIN 

     INSERT INTO @Result 
     VALUES (@_sequence, @_membershipid, @_membershipNo) 

     SET @_sequence = @_sequence + 1 

     FETCH NEXT FROM FulfilCursor INTO @_membershipid, @_membershipNo 
    END 

    CLOSE FulfilCursor 
    DEALLOCATE FulfilCursor 

    RETURN 

    END 




    GO 

我的問題是,當FulfilmentID = 4,I灣添加一個額外的場 - 「投放」

如果已經嘗試了以下內容:

CREATE FUNCTION [dbo].[UDF_FulfilmentBatch](@FulfilmentID INT) RETURNS 
     @Result TABLE (
       [sequence] INT, 
       membershipid BIGINT, 
       membershipNo VARCHAR(255) 
     IF @FulfilmentID = 4 
     BEGIN 
     ,Delivery VARCHAR(255) 
     END 
     ) 
     AS 
     BEGIN 

     DECLARE @_sequence INT 
     DECLARE @_membershipid BIGINT 
     DECLARE @_membershipNo VARCHAR(255) 
IF @FulfilmentID = 4 
     BEGIN 
     DECLARE @_Delivery VARCHAR(255) 
     END 

     SET @_sequence = 1 

     IF @FulfilmentID = 4 
     BEGIN 
      DECLARE FulfilCursor CURSOR FAST_FORWARD FOR 
       SELECT * from VW_FulfilmentExtract_HH 
     END 
    IF @FulfilmentID = 3 
     BEGIN 
      DECLARE FulfilCursor CURSOR FAST_FORWARD FOR 
       SELECT * from VW_FulfilmentExtract_ID 
     END 
     ELSE IF @FulfilmentID = 2 
     BEGIN 
      DECLARE FulfilCursor CURSOR FAST_FORWARD FOR 
       SELECT * from VW_FulfilmentExtract_Art 
     END 
     ELSE 
      DECLARE FulfilCursor CURSOR FAST_FORWARD FOR 
       SELECT * from VW_FulfilmentExtract_Tha 

     OPEN FulfilCursor 

     FETCH NEXT FROM FulfilCursor INTO @_membershipid, @_membershipNo 

     WHILE @@FETCH_STATUS = 0 BEGIN 

      INSERT INTO @Result 
      VALUES (@_sequence, @_membershipid, @_membershipNo IF @FulfilmentID=4 BEGIN @_Delivery ) 

      SET @_sequence = @_sequence + 1 

      FETCH NEXT FROM FulfilCursor INTO @_membershipid, @_membershipNo 
     END 

     CLOSE FulfilCursor 
     DEALLOCATE FulfilCursor 

     RETURN 

     END 




     GO 

但這並沒有工作(請原諒任何語法錯誤,這是這麼一個粗略的打字)

表單搜索網頁似乎沒有太多關於此。可以做到嗎?

+0

你可以用一個簡單的UNION合併查詢其'WHERE'語句檢查參數值來代替這一切。由於避免了遊標,程序將會*更簡單,執行更快*。實際上,N倍更快,其中N是返回記錄的數量 –

+1

您說你有一個存儲過程,但是你創建了一個'FUNCTION' ......並且'@ Result'的原因是什麼?你會用它做什麼? – NickyvV

+0

我會建議*從不*創建過程,爲不同的參數組合返回不同的模式。對於功能這是自動照顧。 – Arvo

回答

2

有很多的問題,在你的代碼:

  • 使用SELECT *
  • 使用光標
  • ...

最後,這是過於複雜,看着很多像應用程序代碼(C#,JAVA,...)

你想做的事情應該做一個單一的選擇(即在一個集數據的)。列名稱也應列在SELECT和FROM之間。

一種選擇是:

CREATE FUNCTION [dbo].[UDF_FulfilmentBatch](@FulfilmentID INT) RETURNS TABLE 
AS 
RETURN (
    SELECT sequence = ROW_NUMBER() Over(Order By (Select 1)) 
     , _membershipid, membershipNo, delivery 
    FROM VW_FulfilmentExtract_HH 
    WHERE @FulfilmentID = 4 

    UNION ALL 

    SELECT sequence = ROW_NUMBER() Over(Order By (Select 1)) 
     , _membershipid, membershipNo, delivery = NULL 
    FROM VW_FulfilmentExtract_ID 
    WHERE @FulfilmentID = 3 

    UNION ALL 

    SELECT sequence = ROW_NUMBER() Over(Order By (Select 1)) 
     , _membershipid, membershipNo, delivery = NULL 
    FROM VW_FulfilmentExtract_Art 
    WHERE @FulfilmentID = 2 

    UNION ALL 

    SELECT sequence = ROW_NUMBER() Over(Order By (Select 1)) 
     , _membershipid, membershipNo, delivery = NULL 
    FROM VW_FulfilmentExtract_Tha 
    WHERE @FulfilmentID = not in (2, 3, 4) 
); 

這裏我用ROW_NUMBER生成您的序列號。

我添加了遞送列,並在不需要時將其設置爲NULL。

您必須更新列名稱。我只是猜測他們。

順便說一句,這不是一個存儲過程,但一個Inline User-Defined Functions

+0

甚至沒有。不需要IF或臨時表。一個簡單的意見聯盟就足夠了。如果聯合中的每個查詢都有一個'WHERE @ FulfilmentID = X'語句,則只會執行其中的一個 –

+0

@Panagiotis Kanavos我沒有想到它。起初,我只關注所有其他問題。你想創建自己的答案,還是可以更新我的消息? –

+0

更新您的。我甚至沒有注意到原始代碼試圖產生一個序列。順便說一句,函數可以更簡化,成爲一個內聯函數(例如只是一個RETURNS(SELECT ...)),不需要臨時表。 –