링크 된 블로그 게시물에 누락 된 세부 사항은 변수가 저장 프로 시저 및 함수로 전달되는 방법과 정확히 일치합니다 ( "OUTPUT 매개 변수 인 경우보다 안전한 참조에 의한 전달 버전"의 질문에 대한 문구) :
TSQL은 copy-in / copy-out 시맨틱을 사용하여 저장 프로 시저 및 함수에 매개 변수를 전달합니다.
... 저장된 프로 시저가 (오류없이) 실행을 마치면 복사 된 프로 시저에서 변경된 내용으로 전달 된 매개 변수를 업데이트하는 복사가 수행됩니다.
이 접근법의 실제 이점은 오류 사례입니다. 저장 프로 시저 실행 도중 오류가 발생하면 매개 변수에 대한 변경 내용이 호출자에게 다시 전파되지 않습니다.
OUTPUT 키워드가 없으면 복사가 수행되지 않습니다.
결론 :
저장된 proc에 대한 매개 변수는 오류가 발생한 경우 저장된 proc의 부분 실행을 반영하지 않습니다.
이 퍼즐의 1 부에서는 매개 변수가 항상 "값으로"전달 된다는 것 입니다. 그리고,이 같은 매개 변수가 표시되어있는 경우에만입니다 OUTPUT
및 저장 프로 시저가 현재 값이 실제로 다시 전송되는 것을 성공적으로 완료됩니다. OUTPUT
값이 실제로 "참조로"전달 된 경우 해당 변수의 메모리 위치에 대한 포인터는 값 자체가 아니라 전달 된 것입니다. 포인터 (예 : 메모리 주소)를 전달하면 저장 프로 시저의 다음 줄에서 오류가 발생하여 실행이 중단 되더라도 변경 사항이 즉시 반영됩니다.
1 부 요약 : 변수 값은 항상 복사됩니다. 그것들은 그들의 메모리 주소에 의해 참조되지 않습니다.
Part 1을 염두에두고, 변수 값을 항상 복사하는 정책은 전달되는 변수가 상당히 클 때 자원 문제를 야기 할 수 있습니다. 내가 BLOB 유형을 처리하는 방법을보고 테스트하지 않았습니다 ( VARCHAR(MAX)
, NVARCHAR(MAX)
, VARBINARY(MAX)
, XML
, 더 이상 사용할 수 없습니다 것들 : TEXT
, NTEXT
,과 IMAGE
),하지만 데이터의 테이블이 매우 큰 수에 전달되는 것을 말하는 것이 안전합니다. TVP 기능을 개발하는 사람들은 멋진 새로운 기능이 건강한 수의 시스템을 파괴하지 못하도록 (즉, 더 확장 가능한 접근 방식을 원하는) 진정한 "기준 별 통과"기능을 원하는 것이 합리적입니다. 당신 이 문서 에서 볼 수 있듯이 그들이 한 일 :
Transact-SQL은 입력 데이터의 복사본을 만들지 않도록 참조로 테이블 반환 매개 변수를 루틴에 전달합니다.
또한이 메모리 관리 문제는 SQL Server 2005에 도입 된 SQLCLR API (TVP는 SQL Server 2008에 도입 됨)에서 찾을 수 있으므로 새로운 개념이 아닙니다. 통과 할 때 NVARCHAR
와 VARBINARY
(A SQLCLR 어셈블리 내에서 .NET 방법에 즉, 입력 매개 변수)를 SQLCLR 코드로 데이터, 당신이 중 하나를 사용하여 "값에 의해"접근로 이동 할 수있는 옵션이 SqlString
또는 SqlBinary
각각을하거나 "참조로 갈 수 있습니다 " SqlChars
또는 SqlBytes
각각 을 사용하여 접근하십시오 . SqlChars
및 SqlBytes
유형은 (최대 2GB 오른쪽) 전체 200메가바이트를 복사에 값을 반대로 큰 값의 작은 덩어리를 당길 수 있도록 .NET CLR로 데이터의 전체 스트리밍 할 수 있습니다.
2 부 요약 : TVP는 본질적으로 "항상 가치를 모방"모델 내에 머무르면 많은 메모리를 소비하고 (따라서 성능 저하) 경향이 있습니다. 따라서 TVP는 진정한 "통과 기준"을 수행합니다.
TYPE
변수 또는 aDECLARE x as TABLE (...)
) 를 수정할 수있는 방법이 없습니까?set @tvp = myfunction(@tvp)
함수의RETURNS
값이 TVP 유형과 동일한 DDL을 가진 테이블 인 경우 대신 함수를 사용하여 메모리 풋 프린트가 더 크더라도이를 수행 할 수 있습니까 ?