在 Borland C++ Builder (BCB) 開發資料庫應用時,處理 SQL Server 的 TEXT、IMAGE、MEMO 等大型二進位物件(BLOB)欄位是常見需求。本文整理使用 TBlobStream 進行 BLOB 讀寫的核心步驟、關鍵設定與完整程式碼範例。
TBlobStream 是 BCB 專為 BLOB 欄位設計的串流類別,建構子需指定欄位與存取模式:
TBlobStream* stream = new TBlobStream(
(TBlobField*)Query->FieldByName("BlobFieldName"),
bmReadWrite // 或 bmRead / bmWrite
);
// 1. 取得 BlobStream
TBlobStream* stream = new TBlobStream(
(TBlobField*)WebQuery->FieldByName("SearchTem"), bmReadWrite);
// 2. 依串流大小配置緩衝區
char* buffer = new char[stream->Size];
// 3. 讀取資料
stream->Read(buffer, stream->Size);
// 4. 使用 buffer 處理資料...
delete[] buffer;
delete stream;
// 1. 確保資料集可編輯
// TTable: Table->ReadOnly = false; Table->Edit();
// TQuery: Query->RequestLive = true; Query->Edit();
TBlobStream* stream = new TBlobStream(
(TBlobField*)WebQuery->FieldByName("SearchTem"), bmReadWrite);
// 2. 準備要寫入的資料指標與長度
char* dataPtr = ...; // 來源資料
int dataLen = ...; // 資料長度
// 3. 寫入
stream->Write(dataPtr, dataLen);
// 4. 送交更新
WebQuery->Post();
delete stream;
預設 WRITETEXT 為非記錄操作,需啟用 select into/bulkcopy 選項:
EXEC sp_dboption 'DatabaseName', 'select into/bulkcopy', 'true'
若直接用 SQL 陳述式寫入 BLOB 失敗,請確認此設定。
// 1. 先插入主鍵記錄(BLOB 欄位暫存 null)
AnsiString sql = "INSERT INTO content(file_id, script, key_image) VALUES('"
+ m_szFileID + "', null, null)";
dmStoryEditor->qryExec->SQL->Clear();
dmStoryEditor->qryExec->SQL->Add(sql);
dmStoryEditor->qryExec->ExecSQL();
dmStoryEditor->qryExec->Close();
// 2. 準備 Blob 資料
LockMemories(NewsScript);
NewsScript.GetEdition(NewsScript.m_ScriptHead.byteEditionNum);
NewsScript.m_pScript = (BYTE*)GlobalLock(NewsScript.m_hScript);
if (NewsScript.m_pScript != NULL) {
// 3. 重新查詢剛插入的記錄,建立資料集關聯
sql = "SELECT file_id, script FROM content WHERE file_id='" + m_szFileID + "'";
dmStoryEditor->qryExec->RequestLive = true; // 關鍵:啟用即時更新
dmStoryEditor->qryExec->SQL->Clear();
dmStoryEditor->qryExec->SQL->Add(sql);
dmStoryEditor->qryExec->Open();
dmStoryEditor->qryExec->First();
dmStoryEditor->qryExec->Edit(); // 進入編輯模式
// 4. 寫入 Blob
TBlobStream* blobStream = new TBlobStream(
(TBlobField*)dmStoryEditor->qryExec->FieldByName("script"), bmReadWrite);
blobStream->Write(NewsScript.m_pScript, NewsScript.m_lScriptRealSize);
// 5. 送交並清理
dmStoryEditor->qryExec->Post();
dmStoryEditor->qryExec->RequestLive = false;
delete blobStream;
}
GlobalUnlock(NewsScript.m_hScript);
UnLockMemories(NewsScript);
| 元件類型 | 寫入前必須設定 |
|---|---|
| TTable | ReadOnly = false → Edit() |
| TQuery | RequestLive = true → Edit() |
Edit() 進入編輯狀態Post() 送交GlobalLock/GlobalUnlock)配合全域記憶體控制碼使用DATALENGTH(欄位名)