SQL | Как перебрать оператор вставки или обновления для повышения производительности и обеспечения его безопасности - PullRequest
0 голосов
/ 19 мая 2019

У меня есть служба, которая почти непрерывно выполняет одну и ту же инструкцию вставки или обновления, и меняются только параметры.

Поскольку мы обрабатываем большое количество записей, мы отправляли вставку несколько запросов вместе в каждом вызове в БД.

К сожалению, в результате получается запрос в 900 строк, который непрерывно отправляется на SQLServer.

Я подумал о способе сократить транспорт и, возможно, о массивной работе по разбору 900-строчного запроса, отправив тело один раз и перебрав параметры, и я пришел к следующему запросу:

DECLARE @par VARCHAR(500) 
DECLARE @sql varchar(max) 
DECLARE db_cursor CURSOR FOR  
SELECT Value FROM STRING_SPLIT ( '181120104;98415;001;''P357LT'''....) 
OPEN db_cursor  
DECLARE @Iteration INT 
SET @Iteration = 1 
WHILE @Iteration <= 10 
BEGIN 
set @sql=' update [orderItemsHistory] set '
FETCH NEXT FROM db_cursor INTO @par 
set @sql=@sql+ '[OrderId]  = ' + @par + ' ,'
FETCH NEXT FROM db_cursor INTO @par 
set @sql=@sql+ ' 
[StoreNo]  = ' + @par + ' ,'
.
.
.

FETCH NEXT FROM db_cursor INTO @par 
set @sql=@sql+ ' 
[ItemPackTime]  = ' + @par + ' ,'
FETCH NEXT FROM db_cursor INTO @par 
set @sql=@sql+ ' 
[TimeToShow] = ' + @par + ' '
FETCH NEXT FROM db_cursor INTO @par 
set @sql = @sql +' where '+ @par 
print(@sql); 
exec(@sql); 
if @@rowcount = 0
 begin FETCH NEXT FROM db_cursor INTO @par 
set @sql='insert into [orderItemsHistory]( [OrderId] , 
[StoreNo] , 
.
.
.
[TimeToShow]) 
 VALUES ('+@par+' )'
print(@sql); 
exec(@sql); 
end 
else 
FETCH NEXT FROM db_cursor INTO @par 
SET @Iteration = @Iteration + 1
END
CLOSE db_cursor 
DEALLOCATE db_cursor

И на самом деле он работает просто отлично, но легко увидеть, что он открывает большие ворота для инъекций sql.

Если я пытаюсь использовать более безопасное и простое решение, и просто использовать?и отправьте мои параметры:

DECLARE @Iteration INT 
SET @Iteration = 1 
WHILE @Iteration <= 11 
BEGIN 
update [orderItemsHistory] set [OrderId]  = ?, 
[StoreNo]  = ?, 
.
.
.
[TimeToShow] = ? 
 where [orderId]= ? And [StoreNo]= ? And [Position]= ?
 if @@rowcount = 0
 begin insert into [orderItemsHistory]( [OrderId] , 
[StoreNo] , 
.
.
.
[TimeToShow]) 
 Values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
)end
SET @Iteration = @Iteration + 1

Я получаю очевидную ошибку:

[err: в DbCon.Exec (), execCounter: 0 ошибка: sql: ожидается39 аргументов, получили 702]

Кто-нибудь знает, как работать с итерацией, более безопасно и эффективно?

...