2009-02-10 150 views
2

我有一个vb.net函数,它根据传入函数的参数创建几个存储过程。如何使用SQL创建多个存储过程

我想将这个vb.Net移动到一个单独的SQL文件(出于维护的原因),但我不知道如何在不创建7个单独的存储过程的情况下在SQL中重新创建它。

我创建了总共20个存储过程,我并不想在SQL文件中创建这么多,因为维护将是一场噩梦。我想知道如果有我如何做它VB.Net下面类似的解决方案:

Private Sub CreateStoredProcedures() 

     CreateSP("SummaryNone", "YEAR([sale].[DateTime])") 
     CreateSP("SummaryUser", "[sale].[User]") 
     CreateSP("Summarysale", "[sale].[sale]") 
     CreateSP("SummaryBatch", "[sale].[Batch]") 
     CreateSP("SummaryDay", "dbo.FormatDateTime([sale].[DateTime], 'yyyy-mm-dd')") 
     CreateSP("SummaryMonth", "dbo.FormatDateTime(dbo.DateSerial(YEAR([sale].[DateTime]), MONTH([sale].[DateTime]), 1), 'yyyy-mm-dd')") 
     CreateSP("SummaryYear", "Year([sale].[DateTime])") 

     Return 
    End Sub 


    Private Sub CreateSP(ByVal vName As String, ByVal vGroup As String) 

     Dim CommandText As String = _ 
         "CREATE PROCEDURE " & vName _ 
         & " @StartDate varchar(50)," _ 
         & " @EndDate varchar(50)" _ 
         & " AS " _ 
         & " SELECT " & vGroup & "     AS GroupField," _ 
         & " Sum([Project].[NumProject])    AS TotalProject," _ 
         & " Sum([Project].[Title])     AS SumTitle," _ 
         & " Sum([Project].[Duration])    AS SumDuration," _ 
         & " Sum([Project].[Info])    AS SumInfo," _ 
         & " Sum([Customer].[NumCustomer]) AS TotalNumCustomer," _ 
         & " Sum([Orders].[NumOrders]) AS TotalNumOrders," _ 
         & " Sum([OrderInspection].[NumInspects])   AS TotalNumInspects," _ 
         & " Sum([OrderInspection].[NumFails])    AS TotalNumFails," _ 
         & " Sum([CustomerInspection].[NumInspects]) AS TotalNumCustomerInspectionInspects," _ 
         & " Sum([CustomerInspection].[NumFails])  AS TotalNumCustomerInspectionFails," _ 
         & " Sum([Measurements].[NumMeasurements]) AS TotalNumMeasurementss" _ 
         & " FROM ((((((sale LEFT JOIN Project ON [sale].[saleId]=[Project].[saleId])" _ 
          & " LEFT JOIN Customer ON [Project].[PrintId]=[Customer].[PrintId])" _ 
          & " LEFT JOIN Orders ON [Project].[PrintId]=[Orders].[PrintId])" _ 
          & " LEFT JOIN OrderInspection  ON [Project].[PrintId]=[OrderInspection].[PrintId])" _ 
          & " LEFT JOIN CustomerInspection ON [Project].[PrintId]=[CustomerInspection].[PrintId])" _ 
          & " LEFT JOIN Measurements ON [Project].[PrintId]=[Measurements].[PrintId])" _ 
         & " WHERE [sale].[DateTime] BETWEEN dbo.FormatDateTime((@StartDate), 'yyyy-mm-dd')" _ 
         & " AND dbo.FormatDateTime((@Enddate),'yyyy-mm-dd')" _ 
         & " GROUP BY " & vGroup & "" _ 
         & " ORDER BY " & vGroup & ";" 

     SqlExecuteNonQuery(CommandText) 

     return 
    End Sub 

我期待着您的意见和答复。

谢谢

回答

3

您可以将模板作为.NET DLL中的嵌入资源存储在文本文件中。为您的动态位设置一些占位符。这将使您当前的解决方案更易于维护。然后你从DLL加载流并保持你的当前实现。

编辑文本文件比嵌入在C#文件中的大块SQL更容易。

如果将其移到单个proc中,您可能会收到性能问题,但您可能会对此感到满意,但请记住,proc也会有一些维护问题。我们通常喜欢避免存储过程中的动态SQL。而7路IF分支是维修的噩梦。

2

我会建议您创建一个单一的存储过程,你打电话。

然后使用动态SQL构建适用于单个存储过程中使用的select语句。

有意义吗?

+0

谢谢,它确实有道理。我会考虑这样做。 – Belliez 2009-02-10 09:16:23

+0

好东西,让我们知道如果你需要进一步的援助。 – 2009-02-10 11:43:16

2

您可以创建一个名为Summary的存储过程,然后将名称和列作为附加参数传递。然后你创建动态SQL并执行它。

1

在我看来,动态构建语句并执行它(在T-SQL中)是最好的选择。 如果所有的pissoble都可以的话,我也可以避免在代码中创建存储过程。存储porcs最大的好处是他们的执行计划被缓存在服务器上。如果你丢弃并重新创建它们,那么这些计划通常会被删除,因为proc被删除。

1

SP的优势在于它是预编译的,并且已经创建了执行计划,同时牢记创建SP时出现的数据。

因此,动态SQL会有性能影响,因为SQL Server无法事先发现哪些索引要使用(或甚至是否使用它们)。由于当前您在之后创建了sp ,所以查询计划已正确创建。切换到动态SQL后,情况并非如此。

你也可以创建一个sp,如果然后条件来照顾各种情况。但是,如果稍后添加更多参数,则需要进行维护。