programing

SQL - 각 레코드에 대한 Call Stored Procedure

css3 2023. 9. 2. 08:45

SQL - 각 레코드에 대한 Call Stored Procedure

select 문의 각 레코드에 대해 저장 프로시저를 호출하는 방법을 찾고 있습니다.

SELECT @SomeIds = (
    SELECT spro.Id 
    FROM SomeTable as spro
    INNER JOIN [Address] addr ON addr.Id = spro.Id 
    INNER JOIN City cty ON cty.CityId = addr.CityId
    WHERE cty.CityId = @CityId
)


WHILE @SomeIds  IS NOT NULL
BEGIN
    EXEC UpdateComputedFullText @SomeIds
END

위의 그런 것은 당연히 안 되는 것이지만, 그런 것을 할 수 있는 방법이 있을까요?

당신은 그것을 위해 커서를 사용해야 합니다.

DECLARE @oneid int -- or the appropriate type

DECLARE the_cursor CURSOR FAST_FORWARD
FOR SELECT spro.Id  
    FROM SomeTable as spro 
        INNER JOIN [Address] addr ON addr.Id = spro.Id  
        INNER JOIN City cty ON cty.CityId = addr.CityId 
    WHERE cty.CityId = @CityId

OPEN the_cursor
FETCH NEXT FROM the_cursor INTO @oneid

WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC UpdateComputedFullText @oneid

    FETCH NEXT FROM the_cursor INTO @oneid
END

CLOSE the_cursor
DEALLOCATE the_cursor

ID를 임시 테이블 변수에 넣은 다음 각 행을 반복합니다. (매우 느린 커서를 사용할 필요는 없습니다.)

   Declare @Keys Table (key integer Primary Key Not Null)
   Insert @Keys(key)
   SELECT spro.Id  
   FROM SomeTable as spro 
       JOIN [Address] addr ON addr.Id = spro.Id  
       JOIN City cty ON cty.CityId = addr.CityId 
   WHERE cty.CityId = @CityId
   -- -------------------------------------------
   Declare @Key Integer
   While Exists (Select * From @Keys)
     Begin
         Select @Key = Max(Key) From @Keys
         EXEC UpdateComputedFullText @Key
         Delete @Keys Where Key = @Key
     End 

편집 삭제는 매우 좁은 고유 인덱스에 대해 구동되는 필터 술어와 함께 사용할 때 느리지 않습니다.그러나 다음과 같이 루프를 만들기만 하면 쉽게 피할 수 있습니다.

Declare @Key Integer = 0
While Exists (Select * From @Keys
              Where key > @Key)
 Begin
     Select @Key = Min(Key) From @Keys
                   Where key > @Key
     EXEC UpdateComputedFullText @Key
     -- Delete @Keys Where Key = @Key No Longer necessary 
 End    

아무도 당신에게 최신 답변을 주지 않아서 놀랐습니다.커서가 잘못되었습니다.당신이 원하는 것은 SP의 논리를 테이블 값 함수(TVF)로 이동한 다음 사용하는 것입니다.

여기 제가 어제 작성한 질문이 있습니다(자세한 내용에 연연하지 말고, 그냥 보세요).CROSS APPLY). 그.CROSS APPLY테이블의 조합을 만듭니다.이 조합의 각 요소는 선택 문의 행 항목에 매개 변수화된 TVF에서 생성됩니다.

SELECT supt.hostname,supt.scriptname, COUNT(*)
FROM Event_Pagehit eph
    INNER JOIN Symboltable_urlpair supf
    ON eph.fromPagePair=supf.id
    INNER JOIN Symboltable_urlpair supt
    ON supt.id=eph.toPagePair
CROSS APPLY dbo.TDFCompanyFormationsUrlClassification(supf.hostname,supf.scriptname) as x
CROSS APPLY dbo.TDFCompanyFormationsUrlClassification(supt.hostname,supt.scriptname) as y
WHERE x.isCompanyFormations=1
AND y.isCompanyFormations=0
GROUP BY supt.hostname,supt.scriptname
ORDER BY COUNT(*) desc

사용할 수 있습니다x그리고.y마치 그것들이 테이블에서 끌어온 것처럼.FROM또는JOIN조항TVF 없이 이 질문을 작성해야 한다면 수백 줄에 이를 것입니다.

참고:

SP를 다시 쓸 수 없는 경우: 저장 프로시저의 결과를 테이블 값 함수에서 결과 테이블에 삽입할 수 있습니다.저는 이런 일을 해본 적이 없으며, 때때로 다른 SQL 서버 구조에 주의사항이 있습니다. 누군가가 다르게 말하지 않는 한, 저는 이것이 사실이라고 생각합니다.

커서 없이 이것을 사용해 보십시오.

DECLARE @id int 

SELECT top 1 @id = spro.Id   
    FROM SomeTable as spro  
        INNER JOIN [Address] addr ON addr.Id = spro.Id   
        INNER JOIN City cty ON cty.CityId = addr.CityId  
    WHERE cty.CityId = @CityId
    ORDER BY spro.id

WHILE @@ROWCOUNT > 0 
BEGIN 
    EXEC UpdateComputedFullText @id 

    SELECT top 1 @id = spro.Id   
    FROM SomeTable as spro  
        INNER JOIN [Address] addr ON addr.Id = spro.Id   
        INNER JOIN City cty ON cty.CityId = addr.CityId  
    WHERE cty.CityId = @CityId 
    and spro.id > @id
    ORDER BY spro.id
END 

RE 커서 위의 두 가지 답변이 모두 정답입니다.그러나 커서 내부에서 실행 중인 코드의 복잡성에 따라 이를 선택한 언어로 삭제하고 결과를 데이터베이스로 삭제하기 전에 코드로 계산을 수행하는 것이 좋습니다.

과거로 돌아가서 많은 커서 작업을 검토하고 많은 경우 성능상의 이유로 코드로 전환했습니다.

커서를 사용해야 합니다.SQL Server 커서 예제

DECLARE @id int
DECLARE cursor_sample CURSOR FOR  
SELECT spro.Id 
FROM SomeTable as spro
    INNER JOIN [Address] addr ON addr.Id = spro.Id 
    INNER JOIN City cty ON cty.CityId = addr.CityId
WHERE cty.CityId = @CityId

OPEN cursor_sample
FETCH NEXT FROM cursor_sample INTO @id 
WHILE @@FETCH_STATUS = 0   
BEGIN  
    EXEC UpdateComputedFullText @id
    FETCH NEXT FROM cursor_sample INTO @id
END   

CLOSE cursor_sample
DEALLOCATE cursor_sample

설정 처리가 가능할 때 행 단위로 처리해야 합니까?

SELECT 결과를 임시 테이블에 넣은 다음, proc를 호출하여 임시 테이블의 내용에 대해 대량 SQL을 수행할 수 있습니다.T-SQL 범위 지정 규칙에 따라 호출된 proc에서 temp 테이블을 사용할 수 있습니다.

표준 커서 솔루션은 악의 대상입니다.두 개의 동일한 FETCH NEXT 문은 유지 관리 악몽에 불과합니다.

더 나은 것은

...declare cursor etc.
While 1=1
 Fetch ...
 if @@FETCH_STATUS <> 0  BREAK
...
End -- While 
..Close cursor etc.

악은 때로 정당화되기도 합니다.sp_send_dbmail 또는 다른 저장 프로시저를 사용하여 알림 이메일을 보내는 설정 기반 접근 방식을 고안해 보십시오.

언급URL : https://stackoverflow.com/questions/2077948/sql-call-stored-procedure-for-each-record