Управление данными типа ntext, text и image

Важное примечаниеВажно!

В будущей версии Microsoft SQL Server эта возможность будет удалена. Избегайте использования этой возможности в новых разработках и запланируйте изменение существующих приложений, в которых она применяется. Используйте вместо этого типы данных varchar(max), nvarchar(max) и varbinary(max). Дополнительные сведения см. в разделе Использование типов данных больших значений.

Типы данных SQL Serverntext, text и image можно использовать для хранения очень больших объемов данных (до 2 ГБ) в одном значении. Одно значение данных обычно имеет больший размер, чем приложение может получить на одном шаге; некоторые величины могут быть большего размера, чем доступный клиенту объем виртуальной памяти. Поэтому для получения таких значений необходимо предпринимать особые действия.

Если значение данных типа ntext, text или image не длиннее, чем строка в Юникоде длиной 4 000 символов, символьная строка длиной 8 000 символов или двоичная строка длиной 8 000 байт соответственно, то на такое значение можно ссылаться в инструкциях SELECT, UPDATE и INSERT точно так же, как и на более короткие типы данных. Например, на столбец типа ntext с коротким значением можно ссылаться в списке выбора инструкции SELECT точно так же, как на столбец nvarchar. Существуют некоторые ограничения, например нельзя напрямую ссылаться на столбцы типа ntext, text или image в предложении WHERE. Эти столбцы могут содержаться в предложении WHERE в качестве параметров функции, возвращающей другой тип данных, например ISNULL, SUBSTRING или PATINDEX, либо в выражениях IS NULL, IS NOT NULL или LIKE.

Обработка больших значений данных

Когда значения данных типа ntext, text и image становятся большими, их необходимо обрабатывать блоками. Интерфейсы API базы данных и языка Transact-SQL содержат функции, позволяющие приложениям поблочно работать с данными типа ntext, text и image.

Интерфейсы API базы данных следуют общему шаблону при обработке длинных столбцов типа ntext, text и image.

  • Для считывания длинного столбца приложение просто включает столбец типа ntext, text или image в список выборки, а затем связывает его с программной переменной, достаточно большой для хранения блока данных разумного размера. Затем приложение выполняет инструкцию и использует функцию или метод API для получения данных из связанной переменой по одному блоку за раз.

  • Для записи длинного столбца приложение выполняет инструкцию INSERT или UPDATE с маркером параметра (?) на месте значения, которое будет помещено в столбец типа ntext, text или image. Маркер параметра (или в случае ADO просто параметр) связан с программной переменной, достаточно большой для хранения блоков данных. Приложение создает цикл, в котором сначала в связанную переменную помещается новый набор данных, а затем вызывается функция или метод API для записи блока данных. Цикл повторяется, пока значение переменной не отправится полностью.

Использование параметра text in row

В SQL Server пользователи могут применять параметр таблицы text in row для хранения данных типа text, ntext или image в строке данных.

Для включения этого параметра выполните хранимую процедуру sp_tableoption, задав text in row в качестве названия параметра, а в качестве значения — on. Максимальный размер большого двоичного объекта (BLOB), например, типа text, ntext или image, который может храниться в строке, по умолчанию равен 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, ntext и image.

Внутристрочные текстовые указатели в SQL Server 2000 отличаются от текстовых указателей в более ранних версиях SQL Server. Внутристрочные текстовые указатели ведут себя как дескрипторы файлов для данных BLOB; раньше текстовые указатели функционировали как адреса для данных BLOB. Поэтому при использовании внутристрочных текстовых указателей помните следующее.

Важное примечаниеВажно!

Хотя внутристрочный текст разрешен в курсоре, внутристрочные текстовые указатели не разрешены. 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. Продолжительность

    Текстовые указатели для строк действительны только внутри транзакции. При фиксации транзакции текстовый указатель становится недействительным.

    Текстовые указатели для строк могут быть недействительны внутри транзакции в том случае, если имеет место какое-либо из следующих действий.

    • Сеанс завершен.

    • Строка данных удаляется в той же транзакции. (Другие транзакции не могут удалять строку данных, так как для них действует блокировка.)

    • Изменилась схема таблицы, которой принадлежит текстовый указатель. Следующие действия, изменяющие схему, делают недействительными текстовые указатели: создание и удаление кластеризованного индекса, изменение или удаление таблицы, усечение таблицы, изменение параметров text in row процедурой sp_tableoption и выполнение процедуры 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

    Можно установить внутристрочный текстовый указатель на текст со значением 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 на одну транзакцию одной базы данных.

Без ограничений.

Блокировка

Пока текстовый указатель не станет недействительным, на строку данных устанавливается общая блокировка.

Блокировки не устанавливаются, если используется транзакции нефиксируемого считывания или если база данных работает в однопользовательском режиме, или доступна только для чтения.

Строка данных не блокируется.

Продолжительность

Становится недействительным в конце транзакции или сеанса при удалении строки или изменении схемы таблицы.

Становится недействительным при удалении строки.

Текст со значением NULL

Доступен сразу после вставки текста со значением NULL.

Доступен сразу после обновления.

Использование данных типа ntext, text, и image с API-интерфейсами баз данных

Ниже приведена сводка методов, при помощи которых API-интерфейсы баз данных обрабатывают данные типа ntext, text и image:

  • ADO

    ADO может сопоставлять столбцы или параметры типа ntext, text и image с объектом Field или Parameter. Для поблочного получения данных используйте метод GetChunk, а для поблочной записи — метод AppendChunk.

  • OLE DB

    OLE DB может использовать интерфейс ISequentialStream для поддержки типов данных ntext, text и image. Метод ISequentialStream::Read считывает длинные данные поблочно, а метод ISequentialStream::Write записывает их поблочно в базу данных. Дополнительные сведения см. в разделе Большие двоичные объекты и объекты OLE.

  • ODBC

    Здесь для обработки длинных данных типов ODBC есть возможность получения данных при выполнении: SQL_WLONGVARCHAR (ntext), SQL_LONGVARCHAR (text) и SQL_LONGVARBINARY (image). Эти типы данных связаны с программной переменной. SQLGetData вызывается для поблочного получения длинных данных, а SQLPutData вызывается для поблочной отправки длинных. Дополнительные сведения см. в разделе Управление столбцами text и image.

  • DB-Library

    Приложения DB-Library также связывают столбцы типа ntext, text и image с переменными программы. Функция dbtxtptr из библиотеки DB-Library используется для получения указателя на столбец с длинным значением в базе данных. Функция dbreadtext используется для считывания длинных данных по блоку за раз. Для поблочной записи длинных данных используются такие функции, как dbwritetext, dbupdatetext и dbmoretext.

    ПримечаниеПримечание

    Доступ к внутристрочному тексту в DB-Library не поддерживается.

Дополнительные сведения см. в разделе Функции для работы с типами данных text и image (Transact-SQL).

См. также

Справочник