Share via


管理 ntext、text 與 image 資料

重要事項重要事項

未來的 Microsoft SQL Server 版本將移除這項功能。請避免在新的開發工作中使用這項功能,並規劃修改目前使用這項功能的應用程式。 請改用 varchar(max)、nvarchar(max) 和 varbinary(max) 資料類型。如需詳細資訊,請參閱<使用大數值資料類型>。

SQL Server ntext、text 和 image 資料類型可以保留極大量的資料,在單一值中可以最大到 2 GB。單一資料值通常都大於應用程式一個步驟所能擷取的大小;有些值可能比用戶端的可用虛擬記憶體還大。因此在擷取這些值時,通常需要一些特殊的步驟。

若 ntext、text 和 image 資料值並沒有比 Unicode (4,000 個字元)、字元 (8,000 個字元) 或二進位字串 (8,000 個字元) 來得長,在 SELECT、UPDATE 與 INSERT 陳述式參考值的方式將和較小的資料類型一樣。例如,在 SELECT 陳述式選取清單中參考包含短值的 ntext 資料行,就和參考 nvarchar 資料行的方式一樣。還有一些限制需要注意,例如您無法直接在 WHERE 子句中參考 ntext、text 或 image 資料行。這些資料行可包含於 WHERE 子句中,作為傳回另一個資料類型 (例如 ISNULL、SUBSTRING 或 PATINDEX) 的函數參數,或用於 IS NULL、IS NOT NULL 或 LIKE 運算式中。

處理較大的資料值

不過當 ntext、text 和 image 資料值越來越大時,它們必須以逐個區塊的方式來處理。Transact-SQL 和資料庫 API 兩者都包含一些函數,允許應用程式以逐個區塊使用 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. 持續期間

    資料列文字指標只在一個交易中有效。當交易被認可時,文字指標將變為無效。

    在交易之中,若發生下列任一個動作,資料列文字指標將變為無效:

    • 工作階段結束。

    • 資料列在相同交易中被刪除。(其他交易無法刪除資料列,因為該資料列會獲得鎖定)。

    • 文字指標所在的資料表結構描述變更。可讓文字指標變為無效的結構描述變更動作包括:建立或卸除叢集索引、更改或卸除資料表、截斷資料表、透過 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 文字之後立即取得。

只在更新之後才能取得。

以資料庫 API 來使用 ntext、text 與 image 資料

這是資料庫 API 處理 ntext、text 和 image 資料的方式摘要:

  • ADO

    ADO 可以將 ntext、text 或 image 資料行或參數對應到 FieldParameter 物件。使用 GetChunk 方法一次一個區塊擷取資料,並以 AppendChunk 方法一次一個區塊寫入資料。

  • OLE DB

    OLE DB 使用 ISequentialStream 介面來支援 ntext、text 和 image 資料類型。ISequentialStream::Read 方法可一次一個區塊讀取長資料,而 ISequentialStream::Write 則一次一個區塊將長資料寫入資料庫中。如需詳細資訊,請參閱<BLOB 與 OLE 物件

  • ODBC

    ODBC 擁有一個稱為「資料執行中」("data-at-execution") 的功能,它可處理長資料的 ODBC 資料類型:SQL_WLONGVARCHAR (ntext)、SQL_LONGVARCHAR (text) 與 SQL_LONGVARBINARY (image)。這些資料類型將繫結至程式變數。然後會呼叫 SQLGetData,以便一次一個區塊擷取長資料,並呼叫 SQLPutData,以便一次一個區塊傳送長資料。如需詳細資訊,請參閱<管理 Text 和 Image 資料行>。

  • DB-Library

    DB-Library 應用程式也會將 ntext、text 和 image 資料行繫結到程式變數。DB-Library 函數 dbtxtptr 是用來取得資料庫中長資料行之位置的指標。dbreadtext 則是用來一次一個區塊讀取長資料。而如 dbwritetextdbupdatetextdbmoretext 等函數,則是用來一次一個區塊寫入長資料。

    [!附註]

    不支援以 DB-Library 來存取資料列文字。

如需詳細資訊,請參閱<Text 和 Image 函數 (Transact-SQL)>。