我还是SQL新手。我做了一个存储过程,里面有一些循环。我想在Delphi中创建一个包含少量参数的存储过程。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_operator6]
@awal DATETIME,
@akhir DATETIME,
@pumpsMotor VARCHAR(500),
@pumpsMobil VARCHAR(500),
@pumpsSolar VARCHAR(500)
AS
BEGIN
DECLARE @tbl_pumpMotor TABLE (pumpnumber INT)
INSERT INTO @tbl_pumpMotor
SELECT *
FROM dbo.SplitList(@pumpsMotor,',')
DECLARE @tbl_pumpMobil TABLE (pumpnumber INT)
INSERT INTO @tbl_pumpMobil
SELECT *
FROM dbo.SplitList(@pumpsMobil,',')
DECLARE @tbl_pumpSolar TABLE (pumpnumber INT)
INSERT INTO @tbl_pumpSolar
SELECT *
FROM dbo.SplitList(@pumpsSolar,',')
DECLARE @var2 VARCHAR(50)
DECLARE @tbl_result TABLE (Nama VARCHAR(MAX),
[shift 1 Motor] INT,
[shift 2 Motor] INT,
[shift 3 Motor] INT,
[shift 1 Mobil] INT,
[shift 2 Mobil] INT,
[shift 3 Mobil] INT,
[shift 1 Solar] INT,
[shift 2 Solar] INT,
[shift 3 Solar] INT)
DECLARE @tbl_shift1 TABLE (shiftid INT)
INSERT INTO @tbl_shift1
SELECT [id]
FROM [shift]
WHERE bizdate BETWEEN @awal AND @akhir
AND shiftworkdayid = 1
declare @tbl_shift2 table (shiftid int)
insert into @tbl_shift2 select [id] from [shift] where bizdate between @awal and @akhir and shiftworkdayid=2
declare @tbl_shift3 table (shiftid int)
insert into @tbl_shift3 select [id] from [shift] where bizdate between @awal and @akhir and shiftworkdayid=3
declare hk_cursor cursor for
select distinct operatorname from [transaction] where [date] between @awal and @akhir and OperatorName<>'RFID'
OPEN hk_cursor
fetch next from hk_cursor into @var2
while (@@fetch_status=0)
BEGIN
insert into @tbl_result
select operator.nama,
shift1Motor.[shift 1 Motor], shift2Motor.[shift 2 Motor], shift3Motor.[shift 3 Motor],
shift1Mobil.[shift 1 Mobil], shift2Mobil.[shift 2 MoBIL], shift3Mobil.[shift 3 MoBIL],
shift1SOLAR.[shift 1 SOLAR], shift2SOLAR.[shift 2 SOLAR], shift3SOLAR.[shift 3 SOLAR]
from
(select top 1 operatorname as Nama from [Transaction] where operatorname=@var2) as operator,
-- ====================================== MOTOR
(SELECT count (distinct [ShiftId]) as [shift 1 Motor]
FROM [Transaction]
where
[date] between @awal and @akhir
and operatorname = @var2
and pumpnumber in ( select pumpnumber from @tbl_pumpMotor)
and shiftid in (select shiftid from @tbl_shift1)
)
as shift1Motor,
(SELECT count (distinct
[ShiftId])
as [shift 2 Motor]
FROM [Transaction]
where
[date] between @awal and @akhir
and operatorname = @var2
and pumpnumber in ( select pumpnumber from @tbl_pumpMotor)
and shiftid in (select shiftid from @tbl_shift2)
)
as shift2Motor,
(SELECT count (distinct [ShiftId])as [shift 3 Motor]
FROM [Transaction]
where
[date] between @awal and @akhir
and operatorname = @var2
and pumpnumber in ( select pumpnumber from @tbl_pumpMotor)
and shiftid in (select shiftid from @tbl_shift3)
)
as shift3Motor,
-- ====================================== MOBIL
(SELECT count (distinct [ShiftId]) as [shift 1 MoBIL]
FROM [Transaction]
where
[date] between @awal and @akhir
and operatorname = @var2
and pumpnumber in ( select pumpnumber from @tbl_pumpMobil)
and shiftid in (select shiftid from @tbl_shift1)
)
as shift1Mobil,
(SELECT count (distinct [ShiftId])as [shift 2 MoBIL]
FROM [Transaction]
where
[date] between @awal and @akhir
and operatorname =@var2
and pumpnumber in ( select pumpnumber from @tbl_pumpMobil)
and shiftid in (select shiftid from @tbl_shift2)
)
as shift2Mobil,
(SELECT count (distinct [ShiftId])as [shift 3 MoBIL]
FROM [Transaction]
where
[date] between @awal and @akhir
and operatorname = @var2
and pumpnumber in ( select pumpnumber from @tbl_pumpMobil)
and shiftid in (select shiftid from @tbl_shift3)
)
as shift3Mobil,
-- ====================================== SOLAR
(SELECT count (distinct [ShiftId]) as [shift 1 SOLAR]
FROM [Transaction]
where
[date] between @awal and @akhir
and operatorname = @var2
and pumpnumber in ( select pumpnumber from @tbl_pumpSolar)
and shiftid in (select shiftid from @tbl_shift1)
)
as shift1SOLAR,
(SELECT count (distinct [ShiftId]) as [shift 2 SOLAR]
FROM [Transaction]
where
[date] between @awal and @akhir
and operatorname = @var2
and pumpnumber in ( select pumpnumber from @tbl_pumpSolar)
and shiftid in (select shiftid from @tbl_shift2)
)
as shift2SOLAR,
(SELECT count (distinct [ShiftId]) as [shift 3 SOLAR]
FROM [Transaction]
where
[date] between @awal and @akhir
and operatorname = @var2
and pumpnumber in ( select pumpnumber from @tbl_pumpSolar)
and shiftid in (select shiftid from @tbl_shift3)
)
as shift3SOLAR
FETCH NEXT from hk_cursor into @var2
END
close hk_cursor
deallocate hk_cursor
select * from @tbl_result
end
以及我如何执行
execute sp_operator6 '2015-8-10','2015-8-15','4,3,33,34,35,36','5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22','23,24,27,28,31,32'
在本地服务器上执行结果25记录花了7分钟。 有没有办法比这种方式更简单地编写这个存储过程? 非常感谢任何帮助。
提前致谢
答案 0 :(得分:0)
首先,您需要开始考虑集合并避免循环,尤其是不需要的循环。
接下来你有一个巨大的交叉连接,这通常不利于性能。
如果这些表变量中有多个记录,则抛弃它们并使用临时表,然后将它们编入索引。
考虑将一个类型列添加到表变量(或临时表)中,并将所有信息放入一个表中。这可能会使用case语句进行聚合变得更加简单。数据透视查询也可能很有用。
您还需要查看执行计划,您可能会遗漏一些有用的索引。