我有一个接受三个参数并使用游标收集数据的存储过程。奇怪的是运行 SP 所需的时间。有时运行需要 5 到 10 分钟,然后只返回 300 行。通过在游标中运行单个查询,数据似乎很快返回。我对为什么将它作为一个整体运行需要这么长时间感到有些困惑。如果有人可以指出我可能需要对我的查询提出的任何错误或修复,将不胜感激。
USE [AW]
GO
/****** Object: StoredProcedure [dbo].[Issue_Report] Script Date: 07/25/2012 15:06:04 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Issue_Report]
@MinDate DateTime,
@MaxDate DateTime,
@PSNumParam varchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Setup Temp Table
DECLARE @TempIssueData TABLE
(
[Date] datetime,
[SerialNum] varchar(MAX),
[LotNum] varchar(MAX),
[CatalogNum] varchar(MAX),
[PSNum] varchar(MAX),
[Description] varchar(MAX),
[ORCaseNum] varchar(MAX),
[UserName] varchar(MAX),
[Issued_From] varchar(MAX),
[Issued_To] varchar(MAX),
[Surgical_Specalty] varchar(MAX),
[surgeon] varchar(50),
[SurgeryEndDate] datetime
)
-- Declare Variables (easier for debugging)
DECLARE @StartDate datetime = @MinDate
DECLARE @EndDate datetime = @MaxDate
DECLARE @Date datetime
DECLARE @SurgeryEndDate datetime
DECLARE @SerialNum varchar(MAX)
DECLARE @LotNum varchar(MAX)
DECLARE @CatalogNum varchar(MAX)
DECLARE @PSNum varchar(MAX)
DECLARE @Description varchar(MAX)
DECLARE @ORCaseNum varchar(MAX)
DECLARE @UserName varchar(MAX)
DECLARE @Issued_From varchar(MAX)
DECLARE @Issued_To varchar(MAX)
DECLARE @Surgical_Specialty varchar(MAX)
DECLARE @Surgeon varchar(50)
DECLARE @ItemID uniqueidentifier
DECLARE @LocationID uniqueidentifier
DECLARE @UserID uniqueidentifier
DECLARE @UnitLocation uniqueidentifier
-- Fix EndDateTime to include the whole day
IF(SELECT CONVERT(varchar,@MaxDate, 108) AS TimeOnly) = '00:00:00'
BEGIN
SET @EndDate = DATEADD(SECOND, 86400,@MaxDate)
END
-- Setup Parameters
IF (@PSNumParam ='') BEGIN SET @PSNumParam = NULL END
-- Setup Cursor
DECLARE curs_GetIssueData CURSOR FOR
SELECT item.ID, item.SerialNumber, item.LotNumber, items.PartNumber, items.CrossRefID, items.Description, item.LocationID
FROM dbo.item WITH (INDEX(Stat_LastUpdated)) INNER JOIN dbo.items ON item.ItemID = items.ID
WHERE (dbo.item.Stat = 3) AND (dbo.item.LastUpdated BETWEEN @StartDate AND @EndDate) AND Tracking='1'
AND CrossRefID = ISNULL(@PSNumParam, CrossRefID)
OPEN curs_GetIssueData
-- Start Reading
FETCH NEXT FROM curs_GetIssueData INTO @ItemID, @SerialNum, @LotNum, @CatalogNum, @PSNum, @Description, @LocationID
WHILE (@@FETCH_STATUS = 0)
-- BEGIN WHILE
BEGIN
SET @Issued_From = NULL
BEGIN
SELECT @Issued_From = ISNULL(Locations.Name, 'N/A')
FROM dbo.Locations
WHERE Locations.ID = @LocationID
END
BEGIN
-- Setup Cursor
DECLARE curs_GetTransData CURSOR FOR
SELECT TOP 1 ORCaseNumber, SurgicalSpecialty, UserID, ORNumber, TransDate, Surgeon, EndDateTime
FROM dbo.transactions
WHERE transactions.ItemID = @ItemID AND transactions.TransactionTypeID in (8,9,10) AND transactions.TransDate BETWEEN @StartDate and @EndDate
ORDER BY transactions.TransDate desc
OPEN curs_GetTransData
-- Start Reading
FETCH NEXT FROM curs_GetTransData INTO @ORCaseNum, @Surgical_Specialty, @UserID, @Issued_To, @Date, @Surgeon, @SurgeryEndDate
WHILE (@@FETCH_STATUS = 0)
-- BEGIN GetTransData WHILE
BEGIN
-- Reset UserName
SET @UserName = NULL
SET @UnitLocation = NULL
BEGIN
SELECT @UnitLocation = Unit.LocationID
FROM dbo.Unit
WHERE UnitType='4' and Unit.LocationID = @LocationID
END
-- Check to see if UserID is NULL
IF @UserID IS NULL AND @UnitLocation IS NOT NULL
BEGIN
SET @UserName = 'CORONA'
END
ELSE
BEGIN
SELECT @UserName = dbo.users.LastName + ', ' + dbo.users.FirstName
FROM dbo.users
WHERE users.ID = @UserID
END
FETCH NEXT FROM curs_GetTransData INTO @ORCaseNum, @Surgical_Specialty, @UserID, @Issued_To, @Date, @Surgeon, @SurgeryEndDate
-- END GetTransData WHILE
END
-- CLEANUP
CLOSE curs_GetTransData
DEALLOCATE curs_GetTransData
END
BEGIN
INSERT INTO @TempIssueData
VALUES(
@Date,
@SerialNum,
@LotNum,
@CatalogNum,
@PSNum,
@Description,
@ORCaseNum,
@UserName,
@Issued_From,
@Issued_To,
@Surgical_Specialty,
@Surgeon,
@SurgeryEndDate
)
END
-- Fetch next record
FETCH NEXT FROM curs_GetIssueData INTO @ItemID, @SerialNum, @LotNum, @CatalogNum, @PSNum, @Description, @LocationID
-- END WHILE
END
-- CLEANUP
CLOSE curs_GetIssueData
DEALLOCATE curs_GetIssueData
SELECT * FROM @TempIssueData ORDER BY [Date] Desc, [Issued_From]
END