Verwalten von ntext-, text- und image-Daten

Wichtiger HinweisWichtig

Diese Funktion wird in zukünftigen Versionen von Microsoft SQL Server nicht mehr bereitgestellt. Verwenden Sie diese Funktion beim Entwickeln neuer Anwendungen nicht, und planen Sie das Ändern von Anwendungen, in denen es zurzeit verwendet wird. Verwenden Sie stattdessen varchar(max)-, nvarchar(max)- und varbinary(max)-Datentypen.Weitere Informationen finden Sie unter Verwenden von Datentypen mit umfangreichen Werten.

Die SQL Server-Datentypen ntext, text und image können außerordentlich hohe Datenmengen (bis zu 2 GB) in einem einzelnen Wert enthalten.Ein einzelner Datenwert ist normalerweise zu groß, um von einer Anwendung in einem Schritt abgerufen werden zu können. Die Werte können sogar zu groß für den auf dem Client verfügbaren virtuellen Arbeitsspeicher sein. Deshalb sind normalerweise spezielle Schritte notwendig, um diese Werte abzurufen.

Wenn ein ntext-, text- und image-Datenwert nicht länger als eine Unicode-Zeichenfolge, Zeichenfolge oder Binärzeichenfolge (4.000 Zeichen, 8.000 Zeichen bzw. 8.000 Byte) ist, kann ähnlich wie bei den kleineren Datentypen in den Anweisungen SELECT, UPDATE und INSERT auf den Wert verwiesen werden. Auf eine ntext-Spalte mit einem kurzen Wert kann z. B. in der Auswahlliste einer SELECT-Anweisung ebenso wie auf eine nvarchar-Spalte verwiesen werden. Es müssen jedoch einige Einschränkungen berücksichtigt werden. So ist es z. B. nicht möglich, in einer WHERE-Klausel direkt auf eine ntext-, text- oder image-Spalte zu verweisen. Diese Spalten können in eine WHERE-Klausel als Parameter einer Funktion, die einen anderen Datentyp zurückgibt (z. B. ISNULL, SUBSTRING oder PATINDEX), oder in einem IS NULL-, IS NOT NULL- oder LIKE-Ausdruck eingefügt werden.

Verarbeitung größerer Datenwerte

Größere Datenwerte vom Typ ntext, text und image müssen blockweise verarbeitet werden. Sowohl Transact-SQL als auch Datenbank-APIs verfügen über Funktionen, die Anwendungen die blockweise Verarbeitung von ntext-, text- und image-Daten ermöglichen.

Die Datenbank-APIs halten sich bei der Behandlung von ntext-, text- und image-Spalten mit langen Daten an ein gemeinsames Muster:

  • Zum Lesen einer Spalte mit langen Daten schließt die Anwendung die ntext-, text- oder image-Spalte einfach in eine Auswahlliste ein und bindet die Spalte dann an eine Programmvariable, die groß genug ist, um einen angemessenen Block der Daten zu speichern. Die Anwendung führt dann die Anweisung aus und verwendet eine API-Funktion oder -Methode, um die Daten blockweise in die gebundene Variable abzurufen.

  • Zum Schreiben einer Spalte mit langen Daten führt die Anwendung eine INSERT- oder UPDATE-Anweisung mit einer Parametermarkierung (?) anstelle des Werts aus, der in der ntext-, text- oder image-Spalte verwendet werden soll. Die Parametermarkierung (oder im Falle von ADO der Parameter) ist an eine Programmvariable gebunden, die groß genug für die Datenblöcke ist. Die Anwendung beginnt die Ausführung einer Schleife, in der sie zuerst den nächsten Datenblock in die gebundene Variable verschiebt und dann eine API-Funktion oder -Methode zum Schreiben dieses Datenblockes aufruft. Dieser Vorgang wird wiederholt, bis der gesamte Datenwert gesendet wurde.

Verwenden von text in row

In SQL Server können die Benutzer die Option text in row für eine Tabelle aktivieren, damit die Tabelle text-, ntext- oder image-Daten in ihrer Datenzeile speichern kann.

Zum Aktivieren der Option führen Sie die gespeicherte sp_tableoption-Prozedur aus, und geben Sie dabei text in row als Optionsnamen und on als Wert der Option an. Die maximale Größe für Daten, die in einer Zeile für ein BLOB (Binary Large Object: text-, ntext- oder image-Daten) gespeichert werden können, beträgt standardmäßig 256 Byte, die Werte können jedoch zwischen 24 und 7000 liegen. Wenn Sie eine maximale Größe angeben möchten, die nicht der Standardeinstellung entspricht, geben Sie als Optionswert eine ganze Zahl an, die innerhalb des Bereichs liegt.

text-, ntext- oder image-Zeichenfolgen werden in der Datenzeile gespeichert, wenn die folgenden Bedingungen erfüllt sind:

  • text in row ist aktiviert.

  • Die Länge der Zeichenfolge unterschreitet den in @OptionValue angegebenen Grenzwert.

  • Es steht genügend Speicherplatz in der Datenzeile zur Verfügung.

Werden BLOB-Zeichenfolgen in der Datenzeile gespeichert, können die text-, ntext- oder image-Zeichenfolgen genauso schnell wie Zeichenfolgen und binäre Zeichenfolgen gelesen und geschrieben werden. SQL Server muss nicht auf gesonderte Seiten zugreifen, um die BLOB-Zeichenfolge zu lesen oder zu schreiben.

Wenn eine text-, ntext- oder image-Zeichenfolge den angegebenen Grenzwert oder den verfügbaren Speicherplatz in der Zeile überschreitet, werden anstelle der Zeichenfolge Zeiger in der Zeile gespeichert. Die Bedingungen zum Speichern der BLOB-Zeichenfolgen sind jedoch weiterhin gültig: für die Zeiger muss genügend Speicherplatz in der Datenzeile vorhanden sein.

Weitere Informationen finden Sie unter sp_tableoption (Transact-SQL).

Verwenden von Textzeigern

Wenn die Option text in row nicht angegeben ist, werden text-, ntext- oder image-Zeichenfolgen außerhalb einer Datenzeile gespeichert; nur die Textzeiger auf diese Zeichenfolgen befinden sich in den Datenzeilen. Textzeiger zeigen auf den Stammknoten einer Struktur, die aus internen Zeigern besteht. Die internen Zeiger sind den Seiten zugeordnet, in denen die Zeichenfolgenfragmente der text-, ntext- und image-Daten tatsächlich gespeichert sind.

Textzeiger in Zeilen in SQL Server 2000 unterscheiden sich von den Textzeigern früherer Versionen von SQL Server. Textzeiger in Zeilen verhalten sich wie Dateihandles für BLOB-Daten; Textzeiger früherer Versionen hingegen funktionieren wie Adressen für die BLOB-Daten. Wenn also Textzeiger in Zeilen verwendet werden, sollten folgende Besonderheiten bedacht werden:

Wichtiger HinweisWichtig

Text in Zeilen ist in einem Cursor zulässig, ein Textzeiger in Zeilen jedoch nicht. SQL Server gibt Fehler 328 zurück, wenn Sie versuchen, einen Cursor mit einem Textzeiger in Zeilen zu deklarieren.

  1. Zahl

    In einer Datenbank können pro Transaktion nur 1024 aktive Textzeiger in Zeilen enthalten sein.

  2. Sperren

    Wenn ein Benutzer einen aktiven Textzeiger erhält, sperrt SQL Server 2000 die Datenzeile und stellt so sicher, dass kein anderer Benutzer die Zeile ändert oder löscht, während der erste Benutzer im Besitz des Textzeigers ist. Die Sperre wird aufgehoben, sobald der Textzeiger ungültig wird. Sie können einen Textzeiger mithilfe von sp_invalidate_textptr (Transact-SQL) für ungültig erklären.

    Ein Textzeiger kann nicht zur Aktualisierung von BLOB-Werten verwendet werden, wenn die Isolationsstufe der Transaktion READ UNCOMMITTED lautet oder wenn sich die Datenbank im schreibgeschützten Modus befindet.

    SQL Server 2000 sperrt die Datenzeile nicht, wenn sich die Datenbank im Einzelbenutzermodus befindet.

    Dies wird anhand der folgenden Tabelle veranschaulicht:

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

    Die folgende Transaktion wird erfolgreich ausgeführt:

    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
    

    Die folgende Transaktion erzeugt einen Fehler:

    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. Dauer

    Textzeiger in Zeilen sind nur innerhalb einer Transaktion gültig. Wenn ein Commit für die Transaktion ausgeführt wird, wird der Textzeiger ungültig.

    Textzeiger in Zeilen können in einer Transaktion durch eine der folgenden Aktionen für ungültig erklärt werden:

    • Die Sitzung wird beendet.

    • Die Datenzeile wird in derselben Transaktion gelöscht. (Andere Transaktionen können eine Datenzeile aufgrund der eingerichteten Sperre nicht löschen.)

    • Das Schema einer Tabelle, in der sich der Textzeiger befindet, wird geändert. Zu den schemaändernden Aktionen, die Textzeiger für ungültig erklären, gehören: Erstellen oder Löschen eines gruppierten Index, Ändern oder Löschen der Tabelle, Abschneiden der Tabelle, Ändern der Option text in row mithilfe von sp_tableoption und Ausführen von sp_indexoption.

    Bei Verwendung des oben genannten Beispiels wäre das folgende Skript in früheren Versionen von SQL Server erfolgreich ausgeführt worden – in SQL Server 2000 hingegen wird ein Fehler generiert.

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

    In SQL Server 2000, muss der Textzeiger in Zeilen in einer Transaktion verwendet werden:

    BEGIN TRAN
    DECLARE @ptrval varbinary(16)
    SELECT @ptrval = TEXTPTR(c2)
    FROM t1
    WHERE c1 = 1
    READTEXT t1.c2 @ptrval 0 1
    COMMIT
    
  4. NULL-Text

    Sie können einen Textzeiger in Zeilen für NULL-Text, der durch INSERT generiert wurde, abrufen. Bisher war es nur möglich, Textzeiger nach der Aktualisierung eines BLOBs auf NULL abzurufen.

    So funktioniert der folgende Code beispielsweise nicht in SQL Server 7.0, wird jedoch in SQL Server 2000 erfolgreich ausgeführt.

    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
    

    In SQL Server 7.0 müssen Sie Folgendes ausführen:

    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'
    

In der folgenden Tabelle werden die Unterschiede zusammengefasst.

Unterschied

Textzeiger in Zeilen

Textzeiger außerhalb von Zeilen

Zahl

Maximal 1024 aktive Textzeiger pro Transaktion pro Datenbank

Unbegrenzt

Sperren

Eine S-Sperre wird auf die Datenzeile angewendet, bis der Zeiger ungültig wird.

Es werden keine Sperren angewendet, wenn die Isolationsstufe der Transaktion READ UNCOMMITTED lautet oder sich die Datenbank im Einzelbenutzermodus oder im schreibgeschützten Modus befindet.

Die Datenzeile wird nicht gesperrt.

Dauer

Wird ungültig am Ende der Transaktion oder der Sitzung oder wenn eine Zeile gelöscht oder das Schema der Tabelle geändert wird.

Wird ungültig, wenn die Zeile gelöscht wird.

NULL-Text

Erhältlich direkt nach dem Einfügen von NULL-Text.

Nur erhältlich nach Aktualisierung.

Verwenden von ntext-, text- und image-Daten mit Datenbank-APIs

Im Folgenden wird zusammengefasst, wie Datenbank-APIs ntext-, text- und image-Daten verarbeiten:

  • ADO

    ADO kann einem Field- oder Parameter-Objekt ntext-, text oder image-Spalten oder -Parameter zuordnen. Verwenden Sie die GetChunk-Methode, um die Daten blockweise abzurufen, und die AppendChunk-Methode, um die Daten blockweise zu schreiben.

  • OLE DB

    OLE DB verwendet die ISequentialStream-Schnittstelle, um die Datentypen ntext, text und image zu unterstützen. Die ISequentialStream::Read-Methode liest die langen Daten blockweise, und ISequentialStream::Write schreibt die langen Daten blockweise in die Datenbank. Weitere Informationen finden Sie unter BLOBs und OLE-Objekte.

  • ODBC

    ODBC verfügt über ein Feature namens Data-at-Execution (Daten-in-Ausführung) zur Handhabung der ODBC-Datentypen für lange Daten: SQL_WLONGVARCHAR (ntext), SQL_LONGVARCHAR (text) und SQL_LONGVARBINARY (image). Diese Datentypen werden an eine Programmvariable gebunden. SQLGetData wird dann aufgerufen, um lange Daten blockweise abzurufen, und SQLPutData wird aufgerufen, um lange Daten blockweise zu senden. Weitere Informationen finden Sie unter Verwalten von Text und Bildspalten.

  • DB-Library

    DB-Library-Anwendungen binden ntext-, text- und image-Spalten ebenfalls an Programmvariablen. Die DB-Library-Funktion dbtxtptr wird verwendet, um einen Zeiger auf den Speicherort der Spalte mit langen Daten in der Datenbank abzurufen. dbreadtext wird verwendet, um die langen Daten blockweise zu lesen. Funktionen wie dbwritetext, dbupdatetext und dbmoretext werden verwendet, um die langen Daten blockweise zu schreiben.

    HinweisHinweis

    Der Zugriff auf Text in Zeilen mithilfe der DB-Library wird nicht unterstützt.

Weitere Informationen finden Sie unter Text- und Bildfunktionen (Transact-SQL).