将sql用户定义的函数重写到存储过程中

时间:2014-03-16 16:16:39

标签: sql-server tsql

美好的一天..我现在已经强调了一周如何使用临时表将这个用户定义的函数重写为存储过程......并且还加快了查询过程。老实说,我认为它对我的sql知识水平来说是压倒性的,如果你能提供帮助我会很高兴...至少对我将要处理的其他sql语句有一个参考...

CREATE FUNCTION SALES  
(  

@SUPPLIERCODE VARCHAR(15),  
@BATCHID VARCHAR(50)  
)  
RETURNS  

@STOCKDETAILS TABLE  
(  

 [ID] CHAR(1),  
 [BATCH RECEIVEDATE] DATETIME,  
 SUPPLIERCODE VARCHAR(15),  
 [NOW - RECEVEDATE] INT,  
 [DUEDATE] VARCHAR(50)  
)  
AS  
BEGIN  

DECLARE @RECEIVEDATE DATETIME,  
  @SUPPLIERCODE1 VARCHAR(15)  

 SELECT TOP 1  
  @RECEIVEDATE = O.ReceivedDate,  
  @SUPPLIERCODE1 = A.SUPPLIERCODE  
 FROM TRANSACT.dbo.FIELDS A WITH(NOLOCK)  
 INNER JOIN TRANSACT.dbo.DELIV O WITH(NOLOCK) ON O.BATCHID = A.BATCHID  


 DECLARE @ID1 TABLE(SUPPLIERCODE VARCHAR(50))  
 INSERT INTO @ID1  
 SELECT P.SUPPLIERCODE  
 FROM  
 (  
  SELECT  
   [SUPPLIERCODE] = SUPPLIERCODE,  
   [TOTAL] = ISNULL(SUM(ITEMPRICE+(ITEMPRICE*.12)),0)  
  FROM TRANSACT.dbo.ProviderDiscount WITH(NOLOCK)  
  WHERE ACQUIREDDATE <> '1900-01-01 00:00:00.000'  
   AND SUPPLIERCODE = @SUPPLIERCODE1  
  GROUP BY SUPPLIERCODE  
 ) P  
 WHERE P.TOTAL <> 0  


 DECLARE @ID TABLE(  
  [BATCH RECEIVEDATE] DATETIME,  
  SUPPLIERCODE VARCHAR(15),  
  ACQUIREDDATE DATETIME,  
  Coverage VARCHAR(20),  
  CoverageItem VARCHAR(10),  
  [NOW - RECEVEDATE] INT,  
  DiscTerm1 INT,DiscTerm2 INT,DiscTerm3 INT,DiscTerm4 INT,DiscTerm5 INT,  
  [NEW ACQUIREDDATE] VARCHAR(50)  
 )  
 INSERT INTO @ID  
 SELECT DISTINCT  
  [BATCH RECEIVEDATE] = @RECEIVEDATE,  
  B.SUPPLIERCODE,  
  B.ACQUIREDDATE,  
  B.Coverage,  
  B.CoverageItem,  
  [NOW - RECEVEDATE] = DATEDIFF(DAY,@RECEIVEDATE,GETDATE()),  
  B.DiscTerm1,B.DiscTerm2,B.DiscTerm3,B.DiscTerm4,B.DiscTerm5,  
  [NEW ACQUIREDDATE] =  
   TRANSACT.dbo.fxnGetIDNewACQUIREDDATE(  
    B.DiscTerm1,  
    B.DiscTerm2,  
    B.DiscTerm3,  
    B.DiscTerm4,  
    B.DiscTerm5,  
    @RECEIVEDATE  
   )  
 FROM TRANSACT.dbo.ProviderDiscount B WITH(NOLOCK)  
 INNER JOIN  
 (  
  SELECT  
   [ACQUIREDDATE] = MAX(ACQUIREDDATE),  
   [REOD] = MAX(REOD)  
  FROM TRANSACT.dbo.ProviderDiscount B2 WITH(NOLOCK)  
  INNER JOIN @ID1 B1 ON B1.SUPPLIERCODE = B2.SUPPLIERCODE  
  WHERE B2.Coverage = @CLAIMTYPE  
   AND B2.ACQUIREDDATE < @RECEIVEDATE  
 ) B3 ON B3.REOD = B.REOD  




    INSERT INTO @STOCKDETAILS  
 SELECT DISTINCT  
  [ID] = 'Y',  
  [BATCH RECEIVEDATE],  
  SUPPLIERCODE,  
  [NOW - RECEVEDATE],  
  [DUEDATE] = MIN([NEW ACQUIREDDATE])  
 FROM @ID  
 WHERE ISNULL([NEW ACQUIREDDATE],'NONE') <> 'NONE'  
 GROUP BY [BATCH RECEIVEDATE], SUPPLIERCODE, [NOW - RECEVEDATE]  

 RETURN  
END

1 个答案:

答案 0 :(得分:1)

评论时间有点长。

您的用户定义函数 使用临时表,只是以表变量的形式,而不是以显式临时表的形式。我不确定从一个切换到另一个会有什么动力。

存储过程更多&#34;一般&#34;比用户定义的功能。例如,他们可以调用其他存储过程并执行动态SQL。要将用户定义的函数转换为存储过程,只需在最终选择之前删除INSERT INTO @STOCKDETAILS语句。

但是,用户定义函数很多更有用。您可以在查询中引用它(在from子句中)。您无法使用存储过程执行此操作。如果可以的话,坚持使用该功能。

编辑:

您可以将声明更改为:

CREATE PROCEDURE SALES  ( 
    @SUPPLIERCODE VARCHAR(15),  
    @BATCHID VARCHAR(50)  
)  
BEGIN
 . . . 

顺便说一句,我认为为存储过程和函数添加前缀是个好主意,这样您就可以轻松识别它们。我会用&#34; usp _&#34;和&#34; udf _&#34;为了这个目的。