문제

선택한 필드 값을 쿼리에서 변수에 저장하고 업데이트 문에 사용하려면 어떻게해야합니까?

내 절차는 다음과 같습니다.

SQL Server 2005 T-SQL 저장 프로 시저를 작성하고 있습니다.

  1. 인보이스 테이블에서 송장 ID 목록을 가져오고 커서로 저장
  2. Cursor에서 송장 ID를 가져 오십시오 -> TMP_KEY 변수
  3. foreach tmp_key는 고객 테이블에서 송장 클라이언트 기본 연락처 ID를 찾습니다.
  4. 기본 연락처 ID로 클라이언트 연락처 키를 업데이트합니다
  5. 커서를 닫습니다

내 코드는 다음과 같습니다.

DECLARE @tmp_key int
DECLARE @get_invckey cursor 

set @get_invckey = CURSOR FOR 
    select invckey from tarinvoice where confirmtocntctkey is null and tranno like '%115876'

OPEN @get_invckey 

FETCH NEXT FROM @get_invckey into @tmp_key

WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    SELECT c.PrimaryCntctKey as PrimaryContactKey
    from tarcustomer c, tarinvoice i
    where i.custkey = c.custkey and i.invckey = @tmp_key

    UPDATE tarinvoice set confirmtocntctkey = PrimaryContactKey where invckey = @tmp_key
    FETCH NEXT FROM @get_invckey INTO @tmp_key
END 

CLOSE @get_invckey
DEALLOCATE @get_invckey

DrimaryContactKey를 저장하고 다음 업데이트 문의 설정 절에서 다시 사용하려면 어떻게해야합니까? int 유형이있는 커서 변수 또는 다른 로컬 변수 만 생성합니까?

도움이 되었습니까?

해결책

DECLARE @tmp_key int
DECLARE @get_invckey cursor 

SET @get_invckey = CURSOR FOR 
    SELECT invckey FROM tarinvoice WHERE confirmtocntctkey IS NULL AND tranno LIKE '%115876'

OPEN @get_invckey 

FETCH NEXT FROM @get_invckey INTO @tmp_key

DECLARE @PrimaryContactKey int --or whatever datatype it is

WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    SELECT @PrimaryContactKey=c.PrimaryCntctKey
    FROM tarcustomer c, tarinvoice i
    WHERE i.custkey = c.custkey AND i.invckey = @tmp_key

    UPDATE tarinvoice SET confirmtocntctkey = @PrimaryContactKey WHERE invckey = @tmp_key
    FETCH NEXT FROM @get_invckey INTO @tmp_key
END 

CLOSE @get_invckey
DEALLOCATE @get_invckey

편집하다:
이 질문은 내가 예상했던 것보다 훨씬 더 많은 견인력을 얻었습니다. 내 답변에서 커서의 사용을 옹호하는 것이 아니라 질문에 따라 값을 할당하는 방법을 보여주지 않습니다.

다른 팁

난 그냥 같은 문제가 있었는데 ...

declare @userId uniqueidentifier
set @userId = (select top 1 UserId from aspnet_Users)

또는 더 짧은 :

declare @userId uniqueidentifier
SELECT TOP 1 @userId = UserId FROM aspnet_Users

이 시도

SELECT @PrimaryContactKey = c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey 
    AND i.invckey = @tmp_key

UPDATE tarinvoice SET confirmtocntctkey = @PrimaryContactKey 
WHERE invckey = @tmp_key
FETCH NEXT FROM @get_invckey INTO @tmp_key

루프 외부 의이 변수를 표준 TSQL 변수로 선언합니다.

또한 커서를 다룰 때뿐만 아니라 모든 유형의 선택을 변수로 선택하는 방법이라는 점에 주목해야합니다.

왜 커서가 필요합니까? 전체 코드 세그먼트는 이것으로 대체 될 수 있으며, 이로 인해 많은 수의 행에서 훨씬 더 빠르게 실행됩니다.

UPDATE tarinvoice set confirmtocntctkey = PrimaryCntctKey 
FROM tarinvoice INNER JOIN tarcustomer ON tarinvoice.custkey = tarcustomer.custkey
WHERE confirmtocntctkey is null and tranno like '%115876'

변수를 안전하게 할당하려면 Set-Select 문을 사용해야합니다.

SET @PrimaryContactKey = (SELECT c.PrimaryCntctKey
    FROM tarcustomer c, tarinvoice i
    WHERE i.custkey = c.custkey 
    AND i.invckey = @tmp_key)

시작과 끝 괄호가 있는지 확인하십시오!

Set-Select 버전이 변수를 설정하는 가장 안전한 방법 인 이유는 두 가지입니다.

1. 선택은 여러 게시물을 반환합니다

다음을 선택하면 여러 게시물이 발생하면 어떻게됩니까?

SELECT @PrimaryContactKey = c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey 
    AND i.invckey = @tmp_key

@PrimaryContactKey 값이 할당됩니다 마지막 게시물 결과에서.

사실로 @PrimaryContactKey 결과에 게시물 당 하나의 값이 할당되므로 결과적으로 Select-Command가 처리중인 마지막 게시물의 값이 포함됩니다.

"Last"가 클러스터 된 인덱스에 의해 결정되거나 클러스터 된 인덱스가 사용되지 않거나 기본 키가 클러스터 된 경우 "마지막"게시물이 가장 최근에 추가 된 게시물이됩니다. 이 동작은 최악의 시나리오에서 테이블의 인덱싱이 변경 될 때마다 변경 될 수 있습니다.

set-select 문을 사용하면 변수가 설정됩니다. null.

2. 선택은 게시물을 반환하지 않습니다

코드의 두 번째 버전을 사용할 때 SELECT가 결과를 전혀 반환하지 않으면 어떻게됩니까?

변수의 가치를 믿는 것과는 반대로 무효가되지 않습니다 - 유지됩니다 이전 가치입니다!

위에서 언급했듯이 SQL은 변수에 값을 할당하기 때문입니다. 게시물 당 한 번 - 결과에 게시물이 포함되어 있지 않으면 변수로 아무것도하지 않음을 의미합니다. 따라서 변수는 성명서를 실행하기 전에 여전히 값을 갖습니다.

set-select 문을 사용하면 값이 될 것입니다 null.

또한보십시오: 변수를 할당 할 때 설정 대 Select?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top