将函数添加到存储过程后,执行时间太长

时间:2014-04-10 23:29:23

标签: sql-server stored-procedures

我有这样的存储过程。

ALTER procedure [dbo].[IBS_fetchreqVehicleinPodium]
   @locid integer=null
as
begin
   SET NOCOUNT ON

   SELECT  
       t.TBarcode, t.PlateNo, t.DelEcode
   FROM    
       transaction_tbl t
   WHERE   
       [status] IN (3,4) 
       AND locid = @locid 
       AND dtime >= getdate()-7 
       OR ([status] = 5 AND DATEDIFF(n, CAST(DelDate AS DATETIME), GETDATE()) <= 3 
           AND locid = @locid AND dtime >= getdate()-7)  
   ORDER BY  
       paydate
end

另外,我想检查每个Tbarcode状态并计算时差,所以我写了一个这样的函数:

ALTER function [dbo].[KRRTtime](@status numeric(18,2), @cardID VARCHAR(50)) 
RETURNS int
AS 
BEGIN
   DECLARE 
     @requestedtime datetime,
     @currentdate datetime,
     @keyroomdate datetime,
     @krrttime int

   IF @status= 3 
   BEGIN
      SELECT @requestedtime = t.Paydate 
      FROM Transaction_tbl t 
      WHERE t.tbarcode = @cardID

      SELECT @currentdate = GETDATE()

      SELECT @krrttime = DATEDIFF(minute, @requestedtime, @currentdate)
   END

   IF @status = 4 OR @status = 5
   BEGIN
      SELECT @requestedtime = t.Paydate 
      FROM Transaction_tbl t 
      WHERE t.tbarcode = @cardID

      SELECT @keyroomdate = t.KeyRoomDate 
      FROM Transaction_tbl t 
      WHERE t.tbarcode = @cardID

      SELECT @krrttime = DATEDIFF(MINUTE,@requestedtime,@keyroomdate)
   END

   RETURN @krrttime
end

然后我在我的存储过程中调用了这个函数..在我的存储过程中添加这个函数后...存储过程的执行时间花了很长时间

如果我执行此存储过程而没有执行速度很快的函数..

1 个答案:

答案 0 :(得分:0)

我没有您的数据库而且您也没有发布您的确切表结构 - 但您可能会这样做:

ALTER procedure [dbo].[IBS_fetchreqVehicleinPodium]
   @locid INTEGER = NULL
AS BEGIN
   SET NOCOUNT ON

   -- I'd be careful with your GETDATE()-7 - what "7" does this subtract? 
   -- Days, months, years? I'd rather be explicit about it!
   DECLARE @TodayMinus7Days DATETIME

   -- assuming you mean "today minus 7 days" here .....
   SET @TodayMinus7Days = DATEDIFF(DAYS, -7, GETDATE())

   SELECT  
       t.TBarcode, t.PlateNo, t.DelEcode,
       -- use a CASE here - depending on the status, return one or the other DATEDIFF
       CASE
          WHEN [Status] = 3 
             THEN DATEDIFF(MINUTE, t.PayDate, GETDATE())
          WHEN [Status] IN (4, 5) 
             THEN DATEDIFF(MINUTE, t.PayDate, t.KeyRoomDate)
          -- just guessing here - if status is neither 3, 4, nor 5 - just return 0 in that case - ADAPT AS NEEDED!
          ELSE 0     
        END AS YourDateDiff  -- give it a meaningful column alias here
   FROM    
       dbo.Transaction_tbl t
   WHERE   
       ([status] IN (3,4) AND locid = @locid AND dtime >= @TodayMinus7Days)
       OR 
       ([status] = 5 AND DATEDIFF(n, CAST(DelDate AS DATETIME), GETDATE()) <= 3 AND locid = @locid AND dtime >= @TodayMinus7Days)
   ORDER BY  
       paydate
END