2016-12-02 12 views
3

Возможно, я задал этот вопрос очень плохо, но я не уверен на 100%, что мне нужно задать.SQL Server: вызов хранимой процедуры с использованием данных таблицы

Я пытаюсь выполнить итерацию по строкам в таблице и вызвать хранимую процедуру, используя данные из строк.

Это код, который у меня уже есть, проблема с этим связана с синхронизацией (1000 строк занимают около 1 минуты);

--Set up a temp table with all non email alerts 
SELECT TOP(1000) 
    RowNum = ROW_NUMBER() OVER(ORDER BY AlertID), 
    a.*, i.ImgData 
INTO 
    #temp 
FROM 
    dbo.ALERTS a 
JOIN 
    dbo.IMAGES i ON i.VehicleID = a.VehicleID 
WHERE 
    a.EmailImageSent = 0 OR a.EmailSent = 0 

DECLARE @MaxRownum INT 
SET @MaxRownum = (SELECT MAX(RowNum) FROM #temp) 

DECLARE @Iter INT 
SET @Iter = (SELECT MIN(RowNum) FROM #temp) 

DECLARE @ImgData VARBINARY(MAX) 

WHILE @Iter <= @MaxRownum 
BEGIN  
    SELECT @VehicleID = VehicleID, @ImgData = ImgData 
    FROM #temp 
    WHERE RowNum = @Iter 

    IF @ImgData IS NOT NULL 
    BEGIN 
     EXEC dbo.someProcedure @VehicleID, @ImgData 
     --SELECT 'Image data found for', @VehicleID, @ImgData 
    END 

    SET @Iter = @Iter + 1 
END 

DROP TABLE #temp 

Есть в любом случае я могу запустить хранимую процедуру (dbo.someProcedure) при использовании заявления на основе набора в качестве входных данных?

Извините, если это было задано раньше, я посмотрел и не смог найти ответ или если этот вопрос недостаточно информативен.

Заранее спасибо

+3

Присоединяйтесь к таблице внутри хранимая процедура, вместо передачи каждый раз, когда идентификатор ... – TheGameiswar

+0

таблица температуры видна в рамках вызываемой процедуры, поэтому создать временную таблицу в внешнюю процедуру, то просто проверьте наличие таблицы temp в вызываемой процедуре, чтобы убедиться и получить доступ к ней, как обычно. – Jeremy

+3

Вы также можете посмотреть параметры таблицы. –

ответ

0

AFAIK sp_send_dbmail нужно будет вызываться один раз для каждого сообщения электронной почты, так как у вас есть цикл здесь или у вас есть цикл внутри dbo.someProcedure.

Все еще я думаю, что вы могли бы внести некоторые улучшения. Используйте курсор FAST_FORWARD вместо того, чтобы создавать переменные итерации и каждый раз возвращаться к таблице, чтобы найти следующую строку (таким образом создавая 1000 сканирований таблицы). Не храните избыточные данные в таблице #temp, только то, что вам нужно. Это ускоряет чтение таблицы.

Попробуйте это:

--Set up a temp table with all non email alerts 
Create Table #temp (VehicleID int Primary Key Clustered, ImgData varbinary(max)); 

INSERT INTO #temp (VehicleID, ImgData) 
SELECT TOP(1000) 
    a.VehicleID, i.ImgData 
FROM 
    dbo.ALERTS a 
JOIN 
    dbo.IMAGES i ON i.VehicleID = a.VehicleID 
WHERE 
    a.EmailImageSent = 0 OR a.EmailSent = 0; 

DECLARE @VehicleID int; 
DECLARE @ImgData VARBINARY(MAX); 
DECLARE Alert_Cursor Cursor Fast_Forward For (
    Select VehicleID, ImgData From #temp); 
OPEN Alert_Cursor; 
FETCH NEXT FROM Alert_Cursor INTO @VehicleID, @ImgData; 

WHILE @@FETCH_STATUS = 0 
BEGIN  
    IF @ImgData IS NOT NULL 
     EXEC dbo.someProcedure @VehicleID, @ImgData; 

    FETCH NEXT FROM Alert_Cursor INTO @VehicleID, @ImgData; 
END 

CLOSE Alert_Cursor; 
DEALLOCATE Alert_Cursor; 

DROP TABLE #temp; 
+0

Спасибо, что нашли время для ответа :) –

+0

@Tealpelican Усилилась ли производительность? Если это так, это поможет будущим читателям, если вы пометите ответ как принятый, если не тогда, я бы тоже хотел это знать. – mendosi

+0

Я добавил это, и, к сожалению, я не видел разницы в таймингах (незначительная разница или 1:06 против 1:08 для новых против старых. Я все еще думаю, что это более чистый путь, чем мой текущий код (выбор только определенного данные для временного ввода и т. д.). Мне просто нужно ограничить количество писем, которые я хочу отправить, возможно, вместо 10. –

Смежные вопросы