我有以下查询:
DECLARE @codeItem VARCHAR(100);
DECLARE @Price DECIMAL(18, 5);
DECLARE @EndDate DATE;
DECLARE @StartDate DATE;
DECLARE Cur CURSOR FOR
SELECT *
FROM myTable
OPEN Cur
FETCH NEXT FROM Cur INTO @codeItem, @Price, @EndDate, @StartDate
WHILE @@fetch_status = 0 BEGIN
EXEC sp_Proc @codeItem, @Price, @EndDate, @StartDate
FETCH NEXT FROM Cur INTO @codeItem, @Price, @EndDate, @StartDate
END
CLOSE Cur
DEALLOCATE Cur
存储过程sp_Proc
:
UPDATE SRC
SET enddate = DATEADD(DAY, -1, @StartDate)
FROM test SRC
WHERE codeItem = @codeItem
AND (@StartDate BETWEEN startdate AND enddate)
INSERT INTO test (codeItem, price, startdate, enddate)
VALUES (@codeItem, @price, @StartDate, @EndDate)
如何优化查询?
删除光标?
如何让它更快?
答案 0 :(得分:4)
您不需要光标,也不需要存储过程。这样的事情应该有效:
update s
set EndDate = dateadd(day, -1 , t.StartDate)
from src s join
mytable t
on s.codeItem = t.codeItem and
(t.StartDate between s.startDate and s.EndDate);
insert into test(codeItem, price, StartDate, EndDate)
select codeItem, price, StartDate, EndDate
from myTable;
update
"关闭"以前的记录。 insert
插入新的。这些是基于集合的操作,因此它们应该比使用游标快得多。
答案 1 :(得分:0)
BEGIN TRY
BEGIN TRANSACTION
UPDATE s
SET enddate = DATEADD(DAY, -1, t.StartDate)
FROM dbo.test s
JOIN dbo.myTable t ON s.codeItem = t.codeItem
WHERE t.StartDate BETWEEN startdate AND enddate
INSERT INTO test (codeItem, price, startdate, enddate)
SELECT codeItem, price, startdate, enddate
FROM myTable
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0 BEGIN
ROLLBACK TRANSACTION
END
PRINT ERROR_MESSAGE()
END CATCH
答案 2 :(得分:0)
如果使用查询比使用游标更快。
例如,对于您的更新查询,您可以使用此查询:
Update SRC set EndDate = dateadd(day,-1, mt.StartDate)
from test SRC
inner join myTable as mt
on mt.codeItem = SRC.codeItem
where mt.StartDate between startDate and EndDate;
并为您插入查询
Insert Into test
select * from myTable;