Как перебрать записи в таблице и для каждой записи вызвать хранимую процедуру

Soloxa
Дата: 10.02.2013 03:53:38
Есть хранимая процедура
которая проверяет статус смс ( по @sms_id) у стороннего провайдера и вносит изменения
в таблицы

PROCEDURE [dbo].[check_sms_status] @sms_id nvarchar(255)


процедура имеет один входной параметр @sms_id
и не имеет выходных параметров
но в функцию ее переделать не могу есть insert и update

есть таблица sms c полем sms_id

Как как перебрать все записи в таблице sms и для каждой записи вызвать

хранимую процедуру
Ken@t
Дата: 10.02.2013 08:49:59
Soloxa,

На выбор
1. Переписать хп
2. Использовать курсор
На выбор
Дата: 10.02.2013 10:15:34
Soloxa,

1 написать _функцию_ которая возвращает статус от стороннего провайдера, update/insert - вне функции
2 написать без процедуры и функции все в одном merge кодом ориентированным на выборку а не строки
Soloxa
Дата: 10.02.2013 10:25:55
Ken@t
Soloxa,

На выбор
1. Переписать хп
2. Использовать курсор


Возможно или нет переписать данную ХП
Я читал что использование курсоров надо избегать

вот полный текст хп

USE [BDSQL]
GO
/****** Object:  StoredProcedure [dbo].[check_sms_status]    Script Date: 10.02.2013 3:15:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[check_sms_status] @sms_id nvarchar(255)


as
BEGIN

DECLARE 
    @url varchar(800) = 'http://alfa-sms.ru:8080/smw/aisms?user=*****&pass=*********&action=status&sms_id=' 
  , @win int 
  , @text varchar (1000)
  , @SMS_CLOSE_TIME varchar (20)
  , @SMSSTC_CODE varchar (20)

  set @url=@url+@sms_id

EXEC sp_OACreate 'Microsoft.XMLHTTP',@win OUT 
EXEC sp_OAMethod @win, 'Open',null,'GET',@url,0
EXEC sp_OAMethod @win,'Send'
EXEC sp_OAGetProperty @win,'ResponseText', @text output
EXEC sp_OADestroy @win 
print @text
if charindex('error',@text)=0 
	begin
   
		set @SMS_CLOSE_TIME = [dbo].[parser](@text, '<SMS_CLOSE_TIME>', '<')
		set @SMSSTC_CODE  =[dbo].[parser](@text, 'SMSSTC_CODE>', '<')
		print @SMS_CLOSE_TIME
		print @SMSSTC_CODE

		if CHARINDEX('НЕ_НАЙДЕНО', @SMS_CLOSE_TIME) = 0		UPDATE sms SET [Статус_получен] =  @SMS_CLOSE_TIME WHERE sms.sms_id = @sms_id 
		if CHARINDEX('НЕ_НАЙДЕНО', @SMSSTC_CODE) = 0		UPDATE sms SET  sms.Статус=  @SMSSTC_CODE WHERE sms.sms_id = @sms_id

				if @SMSSTC_CODE='delivered'
					begin
					
					declare @code as integer, @tel as nvarchar (11) , @sms_text as varchar (2000)
					select @code = [Code_delo] from sms where [sms_id]= @sms_id
					select @tel = [Получатель] from sms where [sms_id]= @sms_id
					select @sms_text = [Текст] from sms where [sms_id]= @sms_id
					
					INSERT INTO Kontakt ([Day/time] ,Code_delo, Coment, Телефон) VALUES (@SMS_CLOSE_TIME,@code,'СМС на телефон '+ @tel + 'ДОСТАВЛЕНО Текст: ' + @sms_text,@tel)
					
					end  
			
	         
     end
		   
       
END


вот на всякий случай код функции parser

USE [BDSQL]
GO
/****** Object:  UserDefinedFunction [dbo].[parser]    Script Date: 10.02.2013 3:18:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER function [dbo].[parser]
(
@in_string varchar(8000),
@pered varchar(20),
@posle varchar(20)
)
returns varchar(1000)
as
BEGIN


DECLARE @z int
DECLARE @z1  int
DECLARE @parser  varchar (1000)
        
  set @z = charindex(@pered,@in_string)
   
    If @z > 0 	
		begin	
		set @z1=charindex(@posle,@in_string,@z+8)               
         set       @in_string = Left(@in_string, @z1 - 1)       
		 set       @in_string = Right(@in_string, @z1 - @z - Len(@pered))      
		 set       @parser = @in_string
		 end
        Else set @parser = 'НЕ_НАЙДЕНО';

RETURN @parser
END
Ennor Tiegael
Дата: 10.02.2013 11:20:19
Soloxa
Я читал что использование курсоров надо избегать
В вашем случае тормозом будет не курсор. Проверьте протокол, может есть возможность запросить статус сразу нескольких смс одновременно. Это наверняка ускорит выполнение.

Ппц технологии конечно. Я-то, наивный, полагал, что там push от провайдера приходит...
qwerty112
Дата: 10.02.2013 11:34:16
Soloxa
вот полный текст хп

				if @SMSSTC_CODE='delivered'
					begin
					
					declare @code as integer, @tel as nvarchar (11) , @sms_text as varchar (2000)
					select @code = [Code_delo] from sms where [sms_id]= @sms_id
					select @tel = [Получатель] from sms where [sms_id]= @sms_id
					select @sms_text = [Текст] from sms where [sms_id]= @sms_id
					
					INSERT INTO Kontakt ([Day/time] ,Code_delo, Coment, Телефон) VALUES (@SMS_CLOSE_TIME,@code,'СМС на телефон '+ @tel + 'ДОСТАВЛЕНО Текст: ' + @sms_text,@tel)
					
					end  


а что это за й.п. ?
даже если сидьно хотелось сделать через переменные, - всё равно, 3-и селекта не нужно - в одном можно,
а "вообще" - не нужны ни переменные / ни селекты - insert into .... select ...
qwerty112
Дата: 10.02.2013 11:44:39
Soloxa
Я читал что использование курсоров надо избегать

надо, хотя у вас и не тот случай, когда на такие "мелочи" стоит заморачиватся

но можно и "избежать" - сгенерировать скрипт для всех sms_id и выполнить его

declare @SQL varchar(max)
set @SQL=(select 'exec [dbo].[check_sms_status] '+cast(sms_id as varchar)+';' from sms for xml path('')) 
exec(@SQL)
Soloxa
Дата: 10.02.2013 12:19:23
Применил курсор
Все работает может не оптимально но пока устраивает
Всем кто откликнулся БОЛЬШОЕ СПАСИБО !

DECLARE  @sms_id    VARCHAR(50)
DECLARE klient_cursor CURSOR LOCAL FOR

SELECT sms_id FROM    sms WHERE     (sms_id IS NOT NULL) AND (Статус_получен IS NULL) 
  

OPEN klient_cursor
FETCH NEXT FROM klient_cursor INTO @sms_id
WHILE @@FETCH_STATUS=0
BEGIN
    
    PRINT @sms_id
exec [dbo].[check_sms_status] @sms_id
-- переход к следующему sms--

    FETCH NEXT FROM klient_cursor  INTO @sms_id
END
CLOSE klient_cursor
DEALLOCATE klient_cursor