我有一个数据库触发器,而不是运行存储过程。
因此,每次将新数据插入表格时,此触发器都会运行。
这是存储过程查询:
已编辑:新查询
declare @transaction_type int
set @transaction_type = (select TransTyp from inserted)
declare @transaction_ctr bigint
set @transaction_ctr = (select TransCtr from inserted)
declare @transaction_no nvarchar(15)
set @transaction_no = (select TransNum from inserted)
declare @transaction_date datetime
set @transaction_date = (select TransDt from inserted)
declare @customer_code nvarchar(10)
set @customer_code = (select CustCode from inserted)
declare @contact nvarchar(15)
set @contact = (select CellNum from inserted)
declare @transaction_info nvarchar(130)
set @transaction_info = (select TransInfo from inserted)
declare @date_received datetime
set @date_received = (select DtRcv from inserted)
declare @is_active int
set @is_active= (select IsActive
from BigESentData.dbo.tbl_sentRegistration
where CellNum = @contact)
declare @value nvarchar(130)
declare @pos int
declare @len int
if @is_active= 0 OR @is_active is null
begin
delete from BigESentData.dbo.tbl_sentTransaction where TransCtr = @transaction_ctr
end
else
begin
--exec parseSentData @transType
/** Inventory */
if @transaction_type = 3
begin
if not exists(select TransCtr from BigEMerchandiser.dbo.tbl_Inventory_H where TransCtr = @transaction_ctr)
begin
insert into BigEMerchandiser.dbo.tbl_Inventory_H
Values(@transaction_ctr,@customer_code, @date_received, @contact)
set @pos = 0
set @len = 0
while charindex('-', @transaction_info, @pos + 1) > 0
begin
set @len = charindex('|', @transaction_info, @pos + 1) - @pos
set @value = substring(@transaction_info, @pos, @len)
insert into BigEMerchandiser.dbo.tbl_Inventory_D(TransCtr, Material, Qty, ExpDt)
select @transaction_ctr,
ltrim(rtrim(left(@value, charindex('-', @value) - 1))) as Material,
replace(substring(@value,charindex('-',@value),len(@value) - charindex('-', reverse(@value)) - charindex('-', @value) + 1),'-', '') as Qty,
reverse(left(reverse(@value),charindex('-', reverse(@value)) - 1))as ExpDt
set @pos = charindex('|', @transaction_info, @pos + @len) + 1
end
end
end
/** Delivery */
if @transaction_type = 2
begin
if not exists(select TransCtr from BigEMerchandiser.dbo.tbl_Delivery_H where TransCtr = @transaction_ctr)
begin
insert into BigEMerchandiser.dbo.tbl_Delivery_H
Values(@transaction_ctr, @transaction_no, @transaction_date, @customer_code, @date_received, @contact)
set @pos = 0
set @len = 0
while charindex('-', @transaction_info, @pos + 1) > 0
begin
set @len = charindex('|', @transaction_info, @pos + 1) - @pos
set @value = substring(@transaction_info, @pos, @len)
insert into BigEMerchandiser.dbo.tbl_Delivery_D(TransCtr, Material, Qty, ExpDt)
select @transaction_ctr,
ltrim(rtrim(left(@value, charindex('-', @value) - 1))) as Material,
replace(substring(@value,charindex('-',@value),len(@value) - charindex('-', reverse(@value)) - charindex('-', @value) + 1),'-', '') as Qty,
reverse(left(reverse(@value),charindex('-', reverse(@value)) - 1))as ExpDt
set @pos = charindex('|', @transaction_info, @pos + @len) + 1
end
end
end
/** ABIS */
if @transaction_type = 1
begin
if not exists(select TransCtr from BigEMerchandiser.dbo.tbl_Abis_H where TransCtr = @transaction_ctr)
begin
insert into BigEMerchandiser.dbo.tbl_Abis_H
Values(@transaction_ctr, @transaction_no, @customer_code, @date_received, @contact)
set @pos = 0
set @len = 0
while charindex('-', @transaction_info, @pos + 1) > 0
begin
set @len = charindex('|', @transaction_info, @pos + 1) - @pos
set @value = substring(@transaction_info, @pos, @len)
insert into BigEMerchandiser.dbo.tbl_Abis_D(TransCtr, Material, Qty, ExpDt)
select @transaction_ctr,
ltrim(rtrim(left(@value, charindex('-', @value) - 1))) as Material,
replace(substring(@value,charindex('-',@value),len(@value) - charindex('-', reverse(@value)) - charindex('-', @value) + 1),'-', '') as Qty,
reverse(left(reverse(@value),charindex('-', reverse(@value)) - 1))as ExpDt
set @pos = charindex('|', @transaction_info, @pos + @len) + 1
end
end
end
/** end of transaction */
end

让我告诉你一个故事如何运行。数据来自Android应用程序。它是超市中商家的应用程序。该应用程序将数据转换为SMS并将数据发送到SQL数据库。
现在,如果将来自应用程序的已发送数据插入数据库,则会触发触发器,并运行上述存储过程。
存储过程按以下顺序运行:
检查 tbl_sentdata 中未加入 tbltransactionheader 的所有记录,如果不是 tbltransactionheader ,请将其插入。
检查 tblsentdata 中未包含 tbltransactiondetail 的所有记录,解析分隔数据,并将每个记录插入一行。
tblsentdata - 来自应用的数据
tbltransactionheader - 标题表
tbltransactiondetail - 详细信息表
以下是该应用的原始数据:
现在,正如您在屏幕截图中看到的那样,应用程序中的数据是分隔的。所以我需要逐个解析它。(在上面的查询中,解析从注释开始" / *循环分隔数据* /")
现在,如果我手动运行存储过程,对于TransTyp 3(库存),则需要很长时间。
在我的猜测中,我上面的查询逐个检查来自 tblsentdata 的所有数据。 所以如果我有100,000条记录,它每次都会检查它,即使数据已经在交易表上。
以下是我的问题:
我认为这是正确的吗?如果触发器触发,则运行查询。然后发送另一条文本消息,即使第一个查询未完成,触发器也会再次运行。然后发送另一条文本消息,触发器再次运行。
我的查询是否是最佳方法?有没有办法更快?我负担不起运行这个查询需要花费很多时间。
更新日期:11/04/2018
感谢 PSK 。在他的帮助下,我能够解决我的问题并最小化查询中的while循环。我刚刚删除了存储过程。我直接从触发器运行查询,只选择插入的数据。
请参阅上面编辑的查询。
谢谢你们。
答案 0 :(得分:3)
您应避免在查询中使用WHILE
,这会严重降低您的查询速度。对于您的情况,您可以轻松避免使用while循环,这将提高查询的性能。
例如
现有代码
WHILE @headerCount > 0
BEGIN
SET @transCtr = (SELECT TOP 1 TransCtr FROM BigESentData.dbo.tbl_sentTransaction WHERE TransCtr NOT IN (SELECT TransCtr FROM BigEMerchandiser.dbo.tbl_Inventory_H) and TransTyp = 3)
IF NOT EXISTS(SELECT TransCtr FROM BigEMerchandiser.dbo.tbl_Inventory_H where TransCtr = @transCtr)
BEGIN
INSERT INTO BigEMerchandiser.dbo.tbl_Inventory_H
SELECT TOP 1 TransCtr, CustCode, DtRcv, CellNum
FROM BigESentData.dbo.tbl_sentTransaction where TransCtr = @transCtr
END
SET @headerCount = @headerCount - 1
END
修改(不用时)
INSERT INTO BigEMerchandiser.dbo.tbl_Inventory_H
SELECT TOP 1 TransCtr, CustCode, DtRcv, CellNum
FROM BigESentData.dbo.tbl_sentTransaction A
WHERE EXISTS
(
SELECT 1 FROM
BigESentData.dbo.tbl_sentTransaction T WHERE TransCtr NOT IN
(SELECT TransCtr FROM BigEMerchandiser.dbo.tbl_Inventory_H) and TransTyp = 3)
AND T.TransCtr = A.TransCtr
)
使用类似的方法,您可以实现第二个while循环。