programing

SQL Server의 임시 테이블 범위

i4 2023. 7. 20. 21:41
반응형

SQL Server의 임시 테이블 범위

한 데이터베이스에서 다른 데이터베이스로 데이터를 가져오고 변환하는 저장 프로시저를 작성했습니다.각 가져오기는 단일 회사 ID를 사용하고 이 회사와 관련된 모든 데이터를 가져옵니다.

변환 단계를 지원하기 위해 임시 테이블을 사용합니다.스크립트 검토의 일환으로 임시 테이블이 아닌 테이블 변수를 사용하라는 지시를 받았습니다.검토자는 두 개의 다른 가져오기를 동시에 실행하면 임시 테이블이 공유되어 가져오기가 손상될 수 있다고 주장합니다.


질문:

  • 두 개의 다른 수입품을 동시에 실행하면 임시 테이블이 공유된다는 것이 사실입니까?
  • 각 통화는 다음과 같습니까?EXEC새 범위를 생성하시겠습니까?

다음은 이 스크립트의 조작된 예입니다.

CREATE PROC [dbo].[ImportCompany]
(
    @CompanyId AS INTEGER
)
AS
EXEC [dbo].[ImportAddress] @CompanyId = @CompanyId 
--Import other data

CREATE PROC [dbo].[ImportAddress]
(
    @CompanyId AS INTEGER
)
AS
    CREATE TABLE #Companies (OldAddress NVARCHAR(128), NewAddress NVARCHAR(128))
    INSERT INTO #Companies(OldAddress, NewAddress)
    SELECT
        Address as OldAddress,
        'Transformed ' + Address as NewAddress
    FROM
        [OldDb].[dbo].[Addresses]
    WHERE
        CompanyId = @CompanyId

    --Do stuff with the transformed data

    DROP TABLE #Companies

EXEC [dbo].[ImportCompany] @CompanyId = 12345

시작:

로컬 임시 테이블은 현재 세션에서만 표시됩니다.

그리고 (더 중요한 것은):

여러 사용자가 동시에 실행할 수 있는 저장 프로시저 또는 응용프로그램에서 로컬 임시 테이블을 작성하는 경우, 데이터베이스 엔진은 다른 사용자가 작성한 테이블을 구분할 수 있어야 합니다. [sic - sessions not users].데이터베이스 엔진은 내부적으로 각 로컬 임시 테이블 이름에 숫자 접미사를 추가하여 이 작업을 수행합니다.

그것은 누가 그들을 공유할 것이라고 말했는지 정확히 반박합니다.


또한, 그럴 필요가 없습니다.DROP TABLE절차가 끝날 때(같은 링크에서 다시):

저장 프로시저에서 작성된 로컬 임시 테이블은 저장 프로시저가 완료되면 자동으로 삭제됩니다.

##글로벌 임시 테이블에 사용됩니다. 여러 가져오기에서 사용할 수 있습니다.

#로컬 임시 테이블에 사용되며 현재/오프라인 범위에서만 사용할 수 있습니다.

한 세션에서 다른 세션의 임시 테이블을 볼 수 없습니다.따라서 임시 테이블을 사용하든 테이블 변수를 사용하든 상관없이 서로 다른 가져오기는 서로에게 영향을 주지 않습니다.

예외는 다음으로 시작하는 글로벌 임시 테이블입니다.##모든 연결에 표시됩니다.

저는 방아쇠에 사용되는 임시 테이블이 왜 이상하게 작동하는지 알아내려고 몇 시간을 버둥거렸을 뿐입니다.그때 나는 임시 테이블이 트리거를 발생시킨 데이터를 삽입하는 데 사용된 저장 프로시저의 임시 테이블과 동일한 이름을 가지고 있다는 것을 깨달았습니다.나는 이것이 나에게 즉시 명백했어야 한다는 것을 이제 알았지만, 그것은 무엇인가가 이치에 맞지 않는 이유를 알아내려고 할 때 가장 명백한 원인을 간과하는 전형적인 경우였습니다.

따라서 저장된 프로시저가 다른 저장된 프로시저를 호출하거나 트리거를 실행할 때 원하지 않는 부작용을 방지하기 위해 템플릿 이름이 이들 전체에서 고유해야 한다는 점을 기억하는 것이 중요합니다.

또한 내부 저장 프로시저에서 다음 코드를 실행해도 예상대로 작동하지 않습니다.외부에 저장된 proc가 temp table name을 잠그는 것처럼 보이기 때문입니다.

IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
    DROP TABLE #TempTable

언급URL : https://stackoverflow.com/questions/18614344/scope-of-temporary-tables-in-sql-server

반응형