[SQL] SQL - 전화는 각 레코드에 대해 저장 프로 시저
SQLSQL - 전화는 각 레코드에 대해 저장 프로 시저
나는 선택 성명의 각 레코드에 대해 저장 프로 시저를 호출 할 수있는 방법을 찾고 있어요.
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
위의 이러한 것은 물론 작동하지 않습니다,하지만 그런 일을 할 수있는 방법은 무엇입니까?
해결법
-
==============================
1.당신은 그것을 위해 커서를 사용해야합니다.
당신은 그것을 위해 커서를 사용해야합니다.
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
-
==============================
2.놀란 아무도 당신에게 최신 답을주지 않았다. 커서는 나쁜. 당신이 원하는 것은 CROSS이 적용 사용 후 테이블 반환 함수 (TVF)로 SP의 논리를 이동하는 것입니다
놀란 아무도 당신에게 최신 답을주지 않았다. 커서는 나쁜. 당신이 원하는 것은 CROSS이 적용 사용 후 테이블 반환 함수 (TVF)로 SP의 논리를 이동하는 것입니다
여기에 내가 어제 쓴 쿼리가 (적용 단지 CROSS 보면, 세부 사항에없는 체류 할). 십자가는 테이블의 조합을 만들어 적용 할 수 있습니다. 이 조합의 각 요소는 select 문의 행 항목에 매개 변수화 된 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를 사용할 수 있습니다. 나는 TVF없이 쿼리를 작성해야한다면 그것은 백 개 라인의 몇 가지에 걸쳐 것이다.
노트 :
당신은 SP를 다시 작성할 수없는 경우 당신은 테이블 반환 함수에서 결과 테이블에 저장 프로 시저의 결과를 삽입 할 수 있어야한다. 그렇지 않으면 나는이 경우 가정 누군가가 말했다 그래서하지 않는 한 -이 일을 적이없는, 때로는 다른 SQL 서버 구조는주의 사항이 있습니다.
-
==============================
3.각 행을 통해 다음으로 반복 임시 테이블 변수로 ID를 넣고 : (당신은 상당히 느려집니다 커서를 사용할 필요가 없습니다)
각 행을 통해 다음으로 반복 임시 테이블 변수로 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
-
==============================
4.커서없이이 일을보십시오
커서없이이 일을보십시오
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
-
==============================
5.RE 커서 위의 답변은 모두 정확합니다. 그러나, 커서의 코드 실행 내부의 복잡성에 따라, 당신은 더 나은 선택의 여지가 귀하의 언어로이를 삭제하고 데이터베이스에 결과를 삭제하기 전에 코드에서 계산을 수행에서 제공 할 수있다.
RE 커서 위의 답변은 모두 정확합니다. 그러나, 커서의 코드 실행 내부의 복잡성에 따라, 당신은 더 나은 선택의 여지가 귀하의 언어로이를 삭제하고 데이터베이스에 결과를 삭제하기 전에 코드에서 계산을 수행에서 제공 할 수있다.
나는 나 자신이 돌아가서 커서 작업을 많이 검토하고, 많은 경우에 성능 향상을 위해 코드에 이러한 전환을 발견했습니다.
-
==============================
6.SQL 서버 커서 예 : 당신은 커서를 사용해야합니다
SQL 서버 커서 예 : 당신은 커서를 사용해야합니다
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
-
==============================
7.당신은 정말 세트 처리를 사용할 수있을 때 행 단위가 처리해야합니까?
당신은 정말 세트 처리를 사용할 수있을 때 행 단위가 처리해야합니까?
그런 다음, 임시 테이블에 SELECT의 결과를 넣어 임시 테이블의 내용에 대해 대량 SQL을 수행하기 위해 시저를 호출 할 수 있습니다. 임시 테이블은 T-SQL 범위 지정 규칙에 따라 호출 시저에 사용할 수 있습니다.
-
==============================
8.표준 커서 솔루션은 악에 따라 악이다. 두 개의 동일한 FETCH NEXT 문은 유지 보수 악몽이다.
표준 커서 솔루션은 악에 따라 악이다. 두 개의 동일한 FETCH NEXT 문은 유지 보수 악몽이다.
더 나은입니다
...declare cursor etc. While 1=1 Fetch ... if @@FETCH_STATUS <> 0 BREAK ... End -- While ..Close cursor etc.
악은 때때로 정당화. 그냥 sp_send_dbmail 또는 다른 저장 프로 시저를 사용하여 알림 이메일을 보내는에 대한 설정 기반의 접근 방식을 고안하려고합니다.
from https://stackoverflow.com/questions/2077948/sql-call-stored-procedure-for-each-record by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 이름이 모음으로 시작하고 끝나는 경우 SQL 쿼리 확인 (0) | 2020.05.20 |
---|---|
[SQL] 열 인덱스 대 복합 VS MySQL의 커버링 (0) | 2020.05.20 |
[SQL] 타임 스탬프에서 폐기 밀리 초 부분 (0) | 2020.05.20 |
[SQL] SQL Server는 테이블 제약을 받기 2008- (0) | 2020.05.20 |
[SQL] 임시 테이블에서 필드 이름을 검색하는 방법 (SQL 서버 2008) (0) | 2020.05.20 |