如何在SQL存储过程中重用代码?

Syl*_*ain 6 sql sql-server code-reuse

我们使用SQL Server 2005.我们所有的数据访问都是通过存储过程完成的.我们的选择存储过程总是返回多个结果集.

例如:

CREATE PROCEDURE hd_invoice_select(@id INT) AS
    SELECT * FROM Invoice WHERE InvoiceID = @id
    SELECT * FROM InvoiceItem WHERE InvoiceID = @id
    SELECT * FROM InvoiceComments WHERE InvoiceID = @id
    RETURN
Run Code Online (Sandbox Code Playgroud)

我们的应用程序的数据访问层基于结果(O/R Mapper样式)构建对象图.

我遇到的问题是我们有许多不同的发票选择存储过程.它们都返回相同的结构,仅用于不同的选择标准.例如,我也有:

CREATE PROCEDURE hd_invoice_selectAllForCustomer(@customerID INT) AS
    SELECT * FROM Invoice WHERE CustomerID = @customerID
    SELECT * FROM InvoiceItem WHERE InvoiceID IN 
        (SELECT InvoiceID FROM Invoice WHERE CustomerID = @customerID)
    SELECT * FROM InvoiceComments WHERE InvoiceID = @id
        (SELECT InvoiceID FROM Invoice WHERE CustomerID = @customerID)
    RETURN
Run Code Online (Sandbox Code Playgroud)

我还有很多其他的,包括:

hd_invoice_selectActive()
hd_invoice_selectOverdue()
hd_invoice_selectForMonth(@year INT, @month INT)
Run Code Online (Sandbox Code Playgroud)

对于很多概念(客户,员工等),我有相同的模式

我们最终复制了大量代码,维护非常困难.当一个概念的"结构"发生变化时,我们必须去修复所有过程并且它非常容易出错.

所以我的问题是:在场景中重用代码的最佳方法是什么?

我们想出了一个使用临时表的解决方案.但它不是很优雅.我会让您分享您的想法,如有必要,我会在即将发布的帖子中发布我的解决方案的详细信息,以获得您对该方法的评论.

谢谢

Chr*_*ter 2

将其发布为第二个答案,因为这是一种不同的方法。如果您使用的是 SQL Server 2008:

CREATE TYPE InvoiceListTableType AS TABLE 
(
    InvoiceId INT
);
GO

CREATE PROCEDURE hd_invoice_selectFromTempTable
(
    @InvoiceList InvoiceListTableType READONLY
)
AS
BEGIN
    SELECT * FROM Invoice WHERE InvoiceID IN
        (SELECT InvoiceId FROM @InvoiceList)

    SELECT * FROM InvoiceItem WHERE InvoiceID IN 
        (SELECT InvoiceId FROM @InvoiceList)

    SELECT * FROM InvoiceComments WHERE InvoiceID IN
        (SELECT InvoiceId FROM @InvoiceList)

    RETURN
END
GO

CREATE PROCEDURE hd_invoice_select(@id INT) AS
BEGIN
    DECLARE @InvoiceList AS InvoiceListTableType;

    SELECT id AS ID 
        INTO @InvoiceList

    EXEC hd_invoice_selectFromTempTable(@InvoiceList)
    RETURN
END
GO

CREATE PROCEDURE hd_invoice_selectAllForCustomer(@customerID INT) AS
BEGIN
    DECLARE @InvoiceList AS InvoiceListTableType;

    SELECT invoiceID as ID
        INTO @InvoiceList
        FROM Invoice WHERE CustomerID = @customerID

    EXEC hd_invoice_selectFromTempTable(@InvoiceList)
    RETURN
END
GO

CREATE PROCEDURE hd_invoice_selectAllActive AS
BEGIN
    DECLARE @InvoiceList AS InvoiceListTableType;

    SELECT invoiceID as ID
        INTO @InvoiceList
        FROM Invoice WHERE Status = 10002

    EXEC hd_invoice_selectFromTempTable(@InvoiceList)
    RETURN
END
GO
Run Code Online (Sandbox Code Playgroud)