TEXTVALID: примеры (SQL)

Проверка указателей text и image с помощью TEXTVALID
Раздел: Функции работы с большими объектами (LOB)
TEXTVALID('table_name.column_name', text_ptr): int

Описание функции TEXTVALID

Функция TEXTVALID в MS SQL Server служит для проверки корректности текстового указателя, связанного с конкретным столбцом типа text, ntext или image. Ее применение актуально при работе с устаревшими типами данных больших объектов (LOB), где операции чтения или обновления данных требуют предварительного получения указателя через функцию TEXTPTR. Проверка валидности указателя помогает избежать ошибок при последующих манипуляциях с данными.

Синтаксис функции:

TEXTVALID ( 'table_name.column_name' , text_pointer )

Аргументы функции:

  • 'table_name.column_name': строковый литерал, указывающий на имя таблицы и столбца. Имена разделяются точкой и заключаются в одинарные кавычки.
  • text_pointer: значение типа varbinary(16), представляющее собой указатель, который необходимо проверить. Обычно это результат функции TEXTPTR.

Возвращаемые значения:

  • 1 (int): указатель является допустимым и может использоваться для операций с данными.
  • 0 (int): указатель недопустим.
  • NULL: функция возвращает NULL, если имя таблицы или столбца указано неверно, либо если проверяемый столбец не относится к типам text, ntext или image.

Базовые примеры работы

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

Пример 1: Проверка валидного указателя.

USE MyDatabase;
GO

-- Создание таблицы с устаревшим типом text
CREATE TABLE Document (Id INT, Content TEXT);
INSERT INTO Document VALUES (1, 'Пример текста');
GO

DECLARE @Ptr VARBINARY(16);
SELECT @Ptr = TEXTPTR(Content) FROM Document WHERE Id = 1;
SELECT TEXTVALID('Document.Content', @Ptr) AS Result;
Result
-------
1

Пример 2: Проверка невалидного (например, нулевого) указателя.

SELECT TEXTVALID('Document.Content', 0x00000000000000000000000000000000) AS Result;
Result
-------
0

Пример 3: Передача NULL в качестве аргумента text_pointer.

SELECT TEXTVALID('Document.Content', NULL) AS Result;
Result
-------
NULL

Схожие функции в MS SQL Server

Прямых аналогов функции TEXTVALID в SQL Server нет, так как она специфична для работы с текстовыми указателями устаревших типов. Однако, для комплексной работы с такими данными используются другие функции, образующие единый инструментарий:

  • TEXTPTR: возвращает 16-байтный указатель на текстовое или бинарное значение. Это обязательный этап перед использованием TEXTVALID.
  • READTEXT: позволяет прочитать часть данных из столбца text, ntext или image, используя валидный указатель.
  • UPDATETEXT и WRITETEXT: применяются для модификации данных в указанных столбцах.

В современных разработках предпочтительнее использование типов данных VARCHAR(MAX), NVARCHAR(MAX) или VARBINARY(MAX), которые не требуют работы с указателями и поддерживают стандартные строковые функции, что упрощает код и повышает его надежность.

Аналоги в других системах управления базами данных

Концепция явных текстовых указателей, как в MS SQL, является устаревшей и не поддерживается в большинстве современных СУБД. Работа с большими объектами (LOB) реализована иначе.

Oracle: Для проверки существования и состояния LOB-объектов используются методы пакета DBMS_LOB, например, DBMS_LOB.ISOPEN.

-- Oracle: Проверка, открыт ли LOB для чтения/записи.
SELECT DBMS_LOB.ISOPEN(some_clob_column) FROM my_table WHERE id = 1;
0 -- если LOB не открыт

PostgreSQL: При использовании типа OID для больших объектов существует функция lo_exists.

-- PostgreSQL: Проверка существования большого объекта по OID.
SELECT lo_exists(123456);
t -- true

MySQL, SQLite: Не имеют механизма указателей. Данные LOB (BLOB, TEXT) обрабатываются как часть строки, и их валидность гарантируется целостностью транзакции. Для извлечения частей данных используются функции, подобные SUBSTRING.

-- MySQL: Работа с частью текста.
SELECT SUBSTRING(long_text_column, 1, 100) FROM my_table;

Частые ошибки и проблемы

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

Ошибка 1: Использование для неподдерживаемых типов данных. Функция возвращает NULL для столбцов, не являющихся text, ntext или image.

CREATE TABLE TestTable (Id INT, Info VARCHAR(100));
INSERT INTO TestTable VALUES (1, 'Текст');

DECLARE @FakePtr VARBINARY(16) = 0x01;
SELECT TEXTVALID('TestTable.Info', @FakePtr) AS Result;
Result
-------
NULL

Ошибка 2: Указание неверного имени таблицы или столбца. Функция также вернет NULL, а не вызовет исключение.

SELECT TEXTVALID('NonExistentTable.Column', 0x01);
Result
-------
NULL

Ошибка 3: Проверка указателя для строки, в которой текстовый столбец имеет значение NULL. Указатель будет невалидным.

INSERT INTO Document (Id, Content) VALUES (2, NULL);
DECLARE @PtrForNull VARBINARY(16);
SELECT @PtrForNull = TEXTPTR(Content) FROM Document WHERE Id = 2;
SELECT TEXTVALID('Document.Content', @PtrForNull) AS Result;
Result
-------
0

История изменений и современный статус

Типы данных text, ntext и image, а также связанные с ними функции (TEXTVALID, TEXTPTR, READTEXT, UPDATETEXT, WRITETEXT) были объявлены устаревшими (deprecated) начиная с Microsoft SQL Server 2005. Основная рекомендация — переход на использование типов VARCHAR(MAX), NVARCHAR(MAX) и VARBINARY(MAX). Эти типы могут хранить данные аналогичного объема, но интегрированы в стандартную модель хранения и обработки строк, что делает ненужным применение механизма указателей. Функция TEXTVALID сохраняется в продукте исключительно для обеспечения обратной совместимости со старыми базами данных и приложениями. В новых проектах ее использование не рекомендуется.

Сложные и специальные случаи применения

Пример 1: Пакетная проверка валидности указателей для всех строк в таблице. Может использоваться для диагностики целостности данных.

Пример sql
SELECT
    Id,
    Content,
    TEXTPTR(Content) AS TextPointer,
    TEXTVALID('Document.Content', TEXTPTR(Content)) AS IsPointerValid
FROM Document;
GO
Id  Content          TextPointer                            IsPointerValid
1   Пример текста    0xFEFF000001000000...                 1
2   NULL             NULL                                  0

Пример 2: Использование в условной логике хранимой процедуры для безопасного обновления данных.

Пример sql
CREATE PROCEDURE AppendToDocument 
    @DocId INT, 
    @AppendText TEXT
AS
BEGIN
    DECLARE @TextPtr VARBINARY(16);
    SELECT @TextPtr = TEXTPTR(Content) FROM Document WHERE Id = @DocId;
    
    IF TEXTVALID('Document.Content', @TextPtr) = 1
    BEGIN
        -- Указатель валиден, можно выполнять UPDATETEXT
        DECLARE @DataLength INT;
        SET @DataLength = DATALENGTH((SELECT Content FROM Document WHERE Id = @DocId));
        IF @DataLength IS NULL SET @DataLength = 0;
        
        UPDATETEXT Document.Content @TextPtr @DataLength 0 @AppendText;
        PRINT 'Текст успешно добавлен.';
    END
    ELSE
        PRINT 'Ошибка: недопустимый текстовый указатель для документа ID=' + CAST(@DocId AS VARCHAR);
END;
GO

-- Вызов процедуры
EXEC AppendToDocument @DocId = 1, @AppendText = ' Дополнение.';

Пример 3: Создание функции-обертки для удобства проверки.

Пример sql
CREATE FUNCTION dbo.IsTextPointerValid (@TableName sysname, @ColumnName sysname, @Pointer VARBINARY(16))
RETURNS BIT
AS
BEGIN
    DECLARE @Result INT;
    SET @Result = TEXTVALID(QUOTENAME(@TableName) + '.' + QUOTENAME(@ColumnName), @Pointer);
    RETURN ISNULL(@Result, 0); -- Преобразуем NULL в 0 для удобства
END;
GO

-- Использование функции
DECLARE @Ptr VARBINARY(16);
SELECT @Ptr = TEXTPTR(Content) FROM Document WHERE Id = 1;
SELECT dbo.IsTextPointerValid('Document', 'Content', @Ptr) AS IsValid;

MS SQL TEXTVALID function comments

En
TEXTVALID Checks whether a given text pointer is valid