簡體   English   中英

如何使用>>准備好的查詢<<使用ODP(Oracle.DataAccess)更新CLOB字段中的數據?

[英]How can I update data in CLOB fields using a >> prepared query << with ODP (Oracle.DataAccess)?

我正在嘗試執行准備好的SQL查詢,該查詢更新Oracle 10g數據庫(10.2.0.1)中的CLOB字段。

如果我從SQL Developer內部執行以下查詢並提供占位符的值,則沒有問題。 但是,如果我通過OracleCommand (Oracle.DataAccess.dll,版本1.102.0.1(我認為),.NET Framework 3.5)執行它,我會收到以下錯誤消息。 請注意,我們不使用默認的oracle客戶端,因為我們需要批量插入。 不幸的是,給定的ODP版本和.NET Framework版本是一項艱難的要求,我們可能不會改變它。

查詢:

UPDATE master_table
SET    description = :description,
       modification_notes = :modification_notes
WHERE  master_id = :master_id;

錯誤:

ORA-00932:不一致的數據類型:預期 - 獲得CLOB

進一步的信息:

參數分配如下:

var param_description = new OracleParameter(":description", OracleDbType.Clob);
param_description.Value = "Test";

我試過以下的事情:

  • to_clob()插入SQL查詢
  • Oracle.DataAccess.Types.OracleClob對象分配給參數。

我也發現了以下描述,但我真的希望能夠保留准備好的查詢。

如何使用C#在Oracle中插入CLOB字段

是否可以通過准備好的查詢來完成此操作?

我附上了一個產生錯誤的完整示例。 DESCRIPTIONMODIFICATION_NOTES是數據庫中CLOB類型的兩列。


輸入數據:

  • 連接: OracleConnection到數據庫
  • master_id:要過濾的主鍵

碼:
免責聲明:我手動輸入以下示例,可能存在實際代碼中沒有的錯誤

var query = "UPDATE master_table " + 
            "SET description = :description " + 
            "    modification_notes = :modification_notes " +
            "WHERE master_id = :master_id";

var param_master_id = new OracleParameter(":master_id", OracleDbType.Int64);
param_master_id.Value = master_id;

var param_description = new OracleParameter(":description", OracleDbType.Clob);
param_description.Value = "Test1";

var param_master_id = new OracleParameter(":modification_notes", OracleDbType.Clob);
param_description.Value = "Test2";

IDbCommand command = new OracleCommand(query, connection);
command.parameters.Add(param_master_id);
command.parameters.Add(param_description);
command.parameters.Add(param_modification_notes);

command.ExecuteNonQuery(); // this line throws an exception

如果要按名稱綁定,則需要將其設置為true。 默認值是按添加的參數的順序綁定。

cmd.BindByName = true; 

編輯:我的答案適用於Clobs的典型用途,其大小大於32k(它們的設計目的)。 如果你知道你將永遠綁定少於32k字節,或者在通常的unicode情況下只有16k字符,你可以綁定為Varchar2,讓你自己不必創建一個臨時的高架。

-

請記住,oracle列中的LOB實際上是一個LOB定位器,一個指向實際數據的指針。 在使用該Lob Locator更新CLOB列之前,需要先創建並填充臨時CLOB。

在Oracle Home的ODP.NET samples目錄中應該有一個LOB目錄,在那里看起來sample5.cs可能是一個很好的起點。 這是一個片段:

  // Set the command
  OracleCommand cmd = new OracleCommand(
    "update multimedia_tab set story = :1 where thekey = 1");
  cmd.Connection = con;
  cmd.CommandType = CommandType.Text; 

  // Create an OracleClob object, specifying no caching and not a NCLOB
  OracleClob clob = new OracleClob(con, false, false);

  // Write data to the OracleClob object, clob, which is a temporary LOB
  string str = "this is a new story";
  clob.Write(str.ToCharArray(), 0, str.Length);

  // Bind a parameter with OracleDbType.Clob
  cmd.Parameters.Add("clobdata", 
                      OracleDbType.Clob, 
                      clob, 
                      ParameterDirection.Input);

  try 
  {
    // Execute command
    cmd.ExecuteNonQuery();

請參閱實際解決方案的已接受答案。

[編輯:前疑似答案]:
經過幾天的測試和調試,我找到了遠離我考慮的所有方案的解決方案:

顯然,您需要在綁定任何其他內容之前先綁定所有 Clob字段 - 即使使用實際占位符而不是使用 :1:2等。

更改綁定順序(即 AddParameter調用的順序)修復了它。

嘗試這個 :

  string Query3 = "  DECLARE " +
                  "str varchar2(32767); " +
                  " BEGIN " +
                  " str := '" + base64ImageRepresentationLogo + "'; " +
                  "  update map_general_settings set value=str where  DESC_AR='LOGO_IMG' ; END; ";
                    command.CommandText = Query3;
                    command.ExecuteNonQuery();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM