首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle CLOB 超 4000 位元組插入實戰:OracleCommand 參數化綁定與 OracleDataAccess 兩大方案完整代碼

     編輯:Oracle 資料庫相關知識

問題根源

Oracle SQL 語句文本長度限制 4000 位元組(VARCHAR2 字面值上限)。直接拼接超長字符串會報 ORA-01704: string literal too long。SQL Server 無此限制(批次提交 26 萬字符測試通過),遷移時必須改寫。

方案一:System.Data.OracleClient(Microsoft 官方,輕量)


using System.Data.OracleClient;

string connStr = "Data Source=ORCL;User ID=app;Password=pwd;";
using (OracleConnection conn = new OracleConnection(connStr))
{
    conn.Open();
    string sql = "INSERT INTO gw_expointlist (id, name, content) VALUES (1, 'name', :clob)";
    using (OracleCommand cmd = new OracleCommand(sql, conn))
    {
        OracleParameter p = new OracleParameter("clob", OracleType.Clob);
        p.Value = hugeText;  // 超過 4000 字符的字符串變量
        cmd.Parameters.Add(p);
        cmd.ExecuteNonQuery();
    }
}

關鍵點:

  • 佔位符 :clob 而非拼接。
  • OracleType.Clob 告知驅動走 LOB 流式寫入路徑。
  • 無需手動處理分塊,驅動內部自動分片。

方案二:Oracle.DataAccess.Client(ODP.NET,功能全、效能強)


using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;

IDbCommand cmd = new OracleCommand();
cmd.CommandText = "INSERT INTO gw_expointlist (id, name, content) VALUES (1, 'name', :clob)";
cmd.Connection = conn;  // 假設 conn 已打開

OracleClob clob = new OracleClob((OracleConnection)conn);
OracleParameter param = new OracleParameter("clob", OracleDbType.Clob, clob, ParameterDirection.Input);
param.Value = hugeText;

cmd.Parameters.Add(param);
cmd.ExecuteNonQuery();

進階用法:流式寫入超大 CLOB(避免 LOH 內存壓力)


using (OracleClob clob = new OracleClob((OracleConnection)conn))
{
    using (Stream writer = clob.GetStream())
    using (StreamReader reader = new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(hugeText))))
    {
        reader.BaseStream.CopyTo(writer);  // 分塊流式傳輸
    }
    // clob 隱式綁定到參數
    OracleParameter p = new OracleParameter("clob", OracleDbType.Clob, clob, ParameterDirection.Input);
    cmd.Parameters.Add(p);
    cmd.ExecuteNonQuery();
}

BLOB 二進制文件插入同理


// OracleClient
OracleParameter p = new OracleParameter("blob", OracleType.Blob);
p.Value = fileBytes;  // byte[]

// ODP.NET
OracleBlob blob = new OracleBlob((OracleConnection)conn);
using (Stream ws = blob.GetStream())
using (FileStream fs = File.OpenRead(path))
    fs.CopyTo(ws);

效能與選型建議

維度System.Data.OracleClientOracle.DataAccess (ODP.NET)
部署需安裝 Oracle Client + 註冊 GACXCopy 部署可行(Managed Driver 純 .NET)
效能基礎原生優化、陣列綁定、Statement Cache
功能基礎類型支援 UDT、REF CURSOR、XMLType、高可用 (FCF/ONS)
維護狀態Microsoft 已棄用(.NET Core 不支援)Oracle 官方長期維護,推薦新專案

避坑清單

  1. 參數名稱區分大小寫:Oracle 參數不區分大小寫,但 .BD 代碼中建議統一小寫 :clob。
  2. 連接字符串 Pooling:啟用連接池 Pooling=true;Min Pool Size=5;Max Pool Size=100,減少物理連接開銷。
  3. LOB 緩存:ODP.NET OracleClob 預設緩存,大對象寫入後建議 clob.Close() 釋放臨時段。
  4. 字符集轉換:確保 .NET 字符串 (UTF-16) → 數據庫字符集 (AL32UTF8/ZHS16GBK) 隱式轉換正確,必要時顯式 Encoding.GetBytes。

總結

棄用 SQL 拼接,擁抱參數化綁定。新專案首選 ODP.NET Managed Driver(NuGet Oracle.ManagedDataAccess),零配置部署、原生效能、全功能支援,完美解決 CLOB/BLOB 大對象寫入難題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved