簡體   English   中英

select 的存儲過程邏輯

[英]Stored procedure logic for select

我有以下程序:

CREATE PROCEDURE sp_types
    @type varchar(100)
AS
BEGIN
    DECLARE @products table(productId int)

    IF @type = 'Merchandise'
    BEGIN
        INSERT INTO @products
            SELECT productId
            FROM dbo.product
            WHERE type = @type
    END
    ELSE IF @type = 'Electronics'
    BEGIN
        INSERT INTO @products
            SELECT productId
            FROM dbo.product
            WHERE type = @type
    END
    ELSE IF @type = 'Home'
    BEGIN
        INSERT INTO @products
            SELECT productId
            FROM dbo.product
            WHERE type = @type
    END
    ELSE
    BEGIN
        INSERT INTO @products
            SELECT productId
            FROM dbo.product
            WHERE type = @type
    END

    /* here we have logic to convert all the productids in the @products table into an XML format
    <products>
      <productId>1</productId>
      <productId>2</productId>
    ....
    ....
    ....
      <productId>100</productId>
    </products>
    */

    /* after we get the XML string, it is passed to another procedure to print out details about the products */
    EXEC sp_products_list @xml = @productXml

END /* procedure ends here */

這是sp_products_list過程:

CREATE PROCEDURE sp_products_list
    @xml XML
AS
BEGIN
    DECLARE @products TABLE (productId int)

    INSERT INTO @products
        SELECT @xml.value('productId','int')
        FROM @xml.nodes('products')

    /* Select statement */
    SELECT
        a.productId, a.productName, 
        b.productRegion, b.ProductQuantity, 
        c.productSupplier
    FROM
        products a
    JOIN 
        productRegion b ON a.productid = b.productid
    JOIN 
        productSupplier c ON c.productRegion = b.productRegion
    WHERE 
        a.productId IN (SELECT productId FROM @products)

END /* procedure end */

sp_products_list由除sp_types過程之外的許多其他過程調用。 我有一個要求,當我將“商品”類型傳遞給sp_types過程時,我需要顯示一些額外的列,如productSupplierRegionproductSupplierCount等。

但是對於 rest 類型,我只需要顯示sp_products_list過程中的 select 語句當前顯示的內容。

如果我只是將我需要的列添加到當前sp_products_list過程中的 select 語句中,那么它們將針對傳遞給sp_types過程的任何類型顯示,這不是我想要的。

我的解決方案:我能想到的解決方案之一是在sp_products_list過程中接收一個 @type 變量作為輸入,並為 select 語句設置一個 if-else 語句。 如果傳入“商品”的類型,則顯示 select 和其他列,否則顯示常規列。

我將來使用這種方法可能面臨的問題是,如果我們想為傳入的不同@type變量添加不同類型的列怎么辦。在這種情況下,我將不得不執行多個 if-else 語句每種類型。 我計划使用動態 SQL 但我的想法被否決了,因為我的團隊不是動態 SQL 的忠實粉絲。

現在,我正在嘗試為這個問題找到一個可能在任何情況下都有效的強大解決方案。 有什么想法或建議嗎? 謝謝!

我建議您將sp_products_list重寫為表值 function,然后您可以將它與您需要的任何額外列連接起來

CREATE OR ALTER FUNCTION dbo.products_list ( @productId int )
RETURNS TABLE    
AS RETURN

    SELECT
        p.productId, p.productName, 
        pr.productRegion, pr.ProductQuantity, 
        ps.productSupplier
    FROM
        products p
    JOIN 
        productRegion pr ON p.productid = pr.productid
    JOIN 
        productSupplier ps ON ps.productRegion = pr.productRegion
    WHERE 
        p.productId = @productId;

GO

然后,您只需在每個程序中使用該 function 即可。 例如。

CREATE PROCEDURE ProductByType
    @type varchar(100)
AS

    IF @type = 'Merchandise'
    BEGIN
        SELECT pl.*, p.OtherColumns, t.OtherTablesColumns
            FROM dbo.product p
            CROSS APPLY dbo.products_list (p.productId) pl
            LEFT JOIN OtherTable t ON SomeCondition
            WHERE p.type = @type;
    END;
    ELSE
    BEGIN
        SELECT pl.*
            FROM dbo.product p
            CROSS APPLY dbo.products_list (p.productId) pl
            WHERE p.type = @type;
    END;

您可能會發現將@type 選擇推@type中會更高效。 然后你可以簡單地做

SELECT pl.*
FROM dbo.products_list_by_type (@type) pl

服務器將從查詢計划中刪除任何不需要的列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM