ntext, text 및 image 데이터 관리

ms191262.note(ko-kr,SQL.90).gif중요:
Microsoft SQL Server의 이후 버전에서는 이 기능이 제거됩니다. 새 개발 작업에서는 이 기능을 사용하지 말고, 현재 이 기능을 사용하는 응용 프로그램은 수정하십시오. 대신 varchar(max), nvarchar(max)varbinary(max) 데이터 형식을 사용하십시오. 자세한 내용은 큰 값 데이터 형식 사용을 참조하십시오.

Microsoft SQL Server 2005 ntext, textimage 데이터 형식은 하나의 값에 많은 양(최대 2GB)의 데이터를 저장할 수 있습니다. 데이터 값 하나가 일반적으로 응용 프로그램에서 한 번에 검색할 수 있는 용량보다 크거나 클라이언트에서 사용할 수 있는 가상 메모리 용량보다 큰 경우도 있습니다. 따라서 이러한 값을 검색하려면 특별한 단계가 필요합니다.

ntext, textimage 데이터 값이 4,000자보다 짧은 유니코드, 8,000자보다 짧은 문자 또는 8,000바이트보다 짧은 이진 문자열인 경우 크기가 적은 데이터 형식과 마찬가지로 SELECT, UPDATE, INSERT 문에서 이러한 값을 참조할 수 있습니다. 예를 들어 짧은 값이 포함된 ntext 열은 nvarchar 열과 마찬가지로 SELECT 문의 선택 목록에서 참조할 수 있습니다. 하지만 WHERE 절에서 ntext, text 또는 image 열을 직접 참조할 수 없는 등의 일부 제한 사항이 있습니다. 이러한 열은 다른 데이터 형식을 반환하는 함수(예: ISNULL, SUBSTRING, PATINDEX)의 매개 변수로 WHERE 절에 포함되거나 IS NULL, IS NOT NULL, LIKE 식에 포함될 수 있습니다.

큰 데이터 값 처리

ntext, textimage 데이터 값이 커지면 블록 단위로 처리해야만 합니다. Transact-SQL과 데이터베이스 API에는 응용 프로그램이 ntext, textimage 데이터를 블록 단위로 사용할 수 있게 하는 함수가 포함되어 있습니다.

데이터베이스 API는 긴 ntext, textimage 열을 처리하는 것과 같은 패턴을 따릅니다.

  • 긴 열을 읽기 위해 응용 프로그램은 선택 목록에 ntext, text 또는 image 열을 포함한 다음 적절한 데이터 블록을 저장할 만큼 큰 프로그램 변수에 해당 열을 바인딩합니다. 이렇게 하면 응용 프로그램에서 해당 문을 실행하고 API 함수나 메서드를 사용하여 한 번에 한 블록씩 데이터를 바인딩된 변수로 가져옵니다.
  • 긴 열을 쓰기 위해 응용 프로그램은 ntext, text 또는 image 열에 값 대신 매개 변수 표식(?)이 있는 INSERT 또는 UPDATE 문을 실행합니다. 매개 변수 표식(또는 ADO의 경우 매개 변수)은 데이터 블록을 저장할 만큼 큰 프로그램 변수에 바인딩됩니다. 응용 프로그램은 다음 데이터 집합을 바인딩된 변수로 이동한 다음 API 함수나 메서드를 호출하여 데이터 블록을 쓰는 루프를 돕니다. 이 과정은 전체 데이터 값이 전송될 때까지 반복됩니다.

text in row 사용

SQL Server 2005에서는 테이블에 text in row 옵션을 사용하여 해당 데이터 행에 text, ntext 또는 image 데이터를 저장할 수 있습니다.

이 옵션을 사용하려면 옵션 이름으로 text in row를 지정하고 옵션 값으로 on을 지정하여 sp_tableoption 저장 프로시저를 실행합니다. text, ntext 또는 image 데이터와 같은 BLOB(Binary Large Object) 행에 저장할 수 있는 최대 크기의 기본값은 256바이트이지만 24에서 7000바이트 사이의 값을 사용할 수 있습니다. 기본값이 아닌 최대 크기를 지정하려면 옵션 값으로 해당 범위 내의 정수를 지정합니다.

다음과 같은 경우 text, ntext 또는 image 문자열은 데이터 행에 저장됩니다.

  • text in row가 설정된 경우
  • 문자열의 길이가 **@OptionValue**에 지정된 제한보다 짧은 경우
  • 데이터 행에 사용할 수 있는 충분한 공간이 있을 경우

BLOB 문자열이 데이터 행에 저장된 경우 문자와 이진 문자열과 마찬가지로 text, ntext 또는 image 문자열을 빠르게 읽고 쓸 수 있습니다. SQL Server에서는 BLOB 문자열을 읽거나 쓰기 위해 별도의 페이지에 액세스할 필요가 없습니다.

text, ntext 또는 image 문자열이 지정된 제한보다 크거나 행에서 사용 가능한 공간보다 큰 경우에는 대신 포인터가 행에 저장됩니다. 하지만 이 경우에도 행에 BLOB 문자열을 저장하기 위한 조건이 적용됩니다. 데이터 행에는 포인터를 유지할 수 있는 충분한 공간도 있어야 합니다.

자세한 내용은 sp_tableoption(Transact-SQL)을 참조하십시오.

텍스트 포인터 사용

text in row 옵션을 지정하지 않으면 text, ntext 또는 image 문자열은 데이터 행 외부에 저장되고 해당 문자열의 텍스트 포인터만 데이터 행에 저장됩니다. 텍스트 포인터는 text, ntextimage 데이터의 문자열 조각이 실제로 저장된 페이지에 대응되는 내부 포인터로 만들어진 트리의 루트 노드를 가리킵니다.

SQL Server 2000의 행 내부 텍스트 포인터는 이전 버전의 SQL Server 텍스트 포인터와는 다릅니다. 행 내부 텍스트 포인터는 BLOB 데이터의 파일 핸들처럼 작동하지만 이전의 텍스트 포인터는 BLOB 데이터의 주소처럼 작동합니다. 따라서 행 내부 텍스트 포인터를 사용할 때는 다음과 같은 특징을 유의해야 합니다.

ms191262.note(ko-kr,SQL.90).gif중요:
커서에 행 내부 텍스트는 허용되지만 행 내부 텍스트 포인터는 허용되지 않습니다. SQL Server에서 행 내부 텍스트 포인터가 포함된 커서를 선언하려고 하면 오류 328이 반환됩니다.
  1. 숫자
    데이터베이스의 트랜잭션 당 최대 1024개의 활성 행 내부 텍스트 포인터가 허용됩니다.

  2. 잠금
    사용자가 활성 텍스트 포인터를 얻으면 SQL Server 2000은 첫 번째 사용자가 텍스트 포인터를 보유한 동안 다른 사용자가 행을 수정하거나 삭제할 수 없도록 데이터 행을 잠급니다. 텍스트 포인터가 무효화되면 잠금이 해제됩니다. 텍스트 포인터를 무효화하려면 sp_invalidate_textptr(Transact-SQL)을 사용합니다.
    트랜잭션 격리 수준이 커밋되지 않은 읽기거나 데이터베이스가 읽기 전용 모드일 경우 BLOB 값을 업데이트할 때 텍스트 포인터를 사용할 수 없습니다.
    SQL Server 2000은 데이터베이스가 단일 사용자 모드일 경우 데이터 행을 잠그지 않습니다.
    예를 들어 다음 테이블의 경우를 생각해 봅시다.

    CREATE TABLE t1 (c1 int, c2 text)
    EXEC sp_tableoption 't1', 'text in row', 'on'
    INSERT t1 VALUES ('1', 'a')
    

    다음 트랜잭션은 성공합니다.

    INSERT t1 VALUES ('1','This is text.')
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    GO
    BEGIN TRAN
    DECLARE @ptr varbinary(16)
    SELECT @ptr = textptr(c2)
    FROM t1
    WHERE c1 = 1
    READTEXT t1.c2 @ptr 0 5
    COMMIT TRAN
    GO
    

    다음 트랜잭션은 실패합니다.

    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
    GO
    BEGIN TRAN
    DECLARE @ptr varbinary(16)
    SELECT @ptr = textptr(c2)
    FROM t1
    WHERE c1 = 1
    WRITETEXT t1.c2 @ptr 'xx'
    COMMIT TRAN
    GO
    
  3. 기간
    행 내부 텍스트 포인터는 트랜잭션 내에서만 유효합니다. 트랜잭션이 커밋되면 텍스트 포인터가 무효화됩니다.
    다음과 같은 경우 트랜잭션 내에서 행 내부 텍스트 포인터가 무효화됩니다.

    • 세션이 끝난 경우
    • 동일한 트랜잭션에서 데이터 행이 삭제된 경우. 잠금 설정 때문에 다른 트랜잭션은 데이터 행을 삭제할 수 없습니다.
    • 텍스트 포인터가 있는 테이블의 스키마가 변경된 경우. 텍스트 포인터를 무효로 만드는 스키마 변경 작업에는 클러스터형 인덱스 만들기나 삭제, 테이블 변경이나 삭제, 테이블 잘라내기, sp_tableoption을 통한 text in row 옵션 변경, sp_indexoption 실행 등이 있습니다.

    위의 예에서 다음 스크립트는 이전 버전의 SQL Server에서는 작동되지만 SQL Server 2000에서는 오류를 발생시킵니다.

    DECLARE @ptrval varbinary(16)
    PRINT 'get error here'
    SELECT @ptrval = TEXTPTR(c2)
    FROM t1
    WHERE c1 = 1
    READTEXT t1.c2 @ptrval 0 1
    

    SQL Server 2000에서 행 내부 텍스트 포인터는 트랜잭션 내에서 사용해야 합니다.

    BEGIN TRAN
    DECLARE @ptrval varbinary(16)
    SELECT @ptrval = TEXTPTR(c2)
    FROM t1
    WHERE c1 = 1
    READTEXT t1.c2 @ptrval 0 1
    COMMIT
    
  4. NULL 텍스트
    INSERT에 의해 생성된 NULL 텍스트에 대해 행 내부 텍스트 포인터를 얻을 수 있습니다. 이전에는 BLOB을 NULL로 업데이트한 후에만 텍스트 포인터를 얻을 수 있었습니다.
    예를 들어 다음 코드는 SQL Server 7.0에서는 작동하지 않지만 SQL Server 2000에서는 작동합니다.

    SET TRANSACTION ISOLATION LEVEL READ COMMITTED
    GO
    INSERT INTO t1 VALUES (4, NULL)
    BEGIN TRAN
    DECLARE @ptrval VARBINARY(16)
    SELECT @ptrval = TEXTPTR(c2)
    FROM t1
    WHERE c1 = 4
    WRITETEXT t1.c2 @ptrval 'x4'
    COMMIT
    

    SQL Server 7.0에서는 다음을 사용해야 합니다.

    INSERT INTO t1 VALUES (4, NULL)
    UPDATE t1 
       SET c2 = NULL 
       WHERE c1 = 4
    DECLARE @ptrval VARBINARY(16)
    SELECT @ptrval = TEXTPTR(c2)
    FROM t1
    WHERE c1 = 4
    WRITETEXT t1.c2 @ptrval 'x4'
    

다음은 위 두 방식의 차이점을 요약한 표입니다.

차이 행 내부 텍스트 포인터가 있을 경우 행 내부 텍스트 포인터가 없을 경우

숫자

데이터베이스의 트랜잭션 당 최대 1024개의 활성 행 내부 텍스트 포인터가 허용됩니다.

제한이 없습니다.

잠금

포인터가 무효화될 때까지 데이터 행에 S 잠금이 설정됩니다.

트랜잭션이 '커밋되지 않은 읽기'이거나 데이터베이스가 '단일 사용자'나 '읽기 전용' 모드이면 잠금이 설정되지 않습니다.

데이터 행이 잠기지 않습니다.

기간

행이 삭제되거나 테이블의 스키마가 변경되면 트랜잭션이나 세션 종료 시 무효화됩니다.

행이 삭제되면 무효화됩니다.

NULL 텍스트

NULL 텍스트를 삽입한 후 바로 설정할 수 있습니다.

업데이트 후에만 설정할 수 있습니다.

ntext, text, image 데이터에 데이터베이스 API 사용

다음은 데이터베이스 API가 ntext, textimage 데이터를 처리하는 방식을 요약한 것입니다.

  • ADO
    ADO는 ntext, text 또는 image 열이나 매개 변수를 Field 또는 Parameter 개체에 매핑할 수 있습니다. GetChunk 메서드를 사용하여 데이터를 한 번에 한 블록씩 검색하고 AppendChunk 메서드를 사용하여 데이터를 한 번에 한 블록씩 씁니다.

  • OLE DB
    OLE DB는 ISequentialStream 인터페이스를 사용하여 ntext, textimage 데이터 형식을 지원합니다. ISequentialStream::Read 메서드는 긴 데이터를 한 번에 한 블록씩 읽고 ISequentialStream::Write는 긴 데이터를 한 번에 한 블록씩 데이터베이스에 씁니다. 자세한 내용은 BLOBs and OLE Objects를 참조하십시오.

  • ODBC
    ODBC에는 긴 데이터의 ODBC 데이터 형식을 처리하기 위한 "실행 시 데이터"라는 기능이 있습니다. 긴 데이터의 ODBC 데이터 형식은 SQL_WLONGVARCHAR(ntext), SQL_LONGVARCHAR(text) 및 SQL_LONGVARBINARY(image)입니다. 이러한 데이터 형식은 프로그램 변수에 바인딩됩니다. 그런 다음 SQLGetData가 호출되어 긴 데이터를 한 번에 한 블록씩 가져오고 SQLPutData가 호출되어 긴 데이터를 한 번에 한 블록씩 전송합니다. 자세한 내용은 Managing Text and Image Columns를 참조하십시오.

  • DB-Library
    DB-Library 응용 프로그램도 ntext, textimage 열을 프로그램 변수에 바인딩합니다. DB-Library 함수인 dbtxtptr을 사용하여 데이터베이스에서 긴 열이 발생한 위치에 대한 포인터를 가져오고 dbreadtext를 사용하여 긴 데이터를 한 번에 한 블록씩 읽습니다. dbwritetext, dbupdatetextdbmoretext 등의 함수는 긴 데이터를 한 번에 한 블록씩 쓰는 데 사용됩니다.

    [!참고] DB-Library에서 행 내부 텍스트 액세스는 지원되지 않습니다.

자세한 내용은 텍스트 및 이미지 함수(Transact-SQL)를 참조하십시오.

참고 항목

관련 자료

DATALENGTH(Transact-SQL)
데이터 형식(Transact-SQL)

도움말 및 정보

SQL Server 2005 지원 받기