正在将字符串数据插入blob

本文关键字:插入 blob 数据 字符串 | 更新日期: 2023-09-27 17:59:54

嗨,我在尝试使用C#将字符串数据插入Oracle中的blob时遇到问题。我在sql编辑器的"Toad"中使用了这句话,它插入了行,没有任何问题,所以这就是代码的来源。

INSERT INTO STORAGE ( STRG_ID, APPL_ID, TASK_ID, PARM_TYPE_ID,       PARM_VAL_TXT,APPL_ITEM_TXT) VALUES (STRG_ID_SEQ.nextval, 2, 1, 1, 'cow',utl_raw.cast_to_raw('some string'))

表格是:

strg_id number, Appl_id number, task_id number , Parm_val_text varchar2(250), Appl_item_txt blob

字符串数据将是大约42kjson文件,但目前我甚至无法获得一个5个字符的字符串。我已经尝试了我能想到的一切,但我是Oracle的新手,主要是Sql Server。我在网上找到了一些东西,下面就是你看到的。我试过:

 try
    {
        using (connection)
        {
            using (var cmd = connection.CreateCommand())
            {
                cmd.CommandType = CommandType.Text;
                cmd.BindByName = true;
                cmd.CommandText =
                    "INSERT INTO CDP.STORAGE (STRG_ID, APPL_ID, TASK_ID, PARM_TYPE_ID, PARM_VAL_TXT,APPL_ITEM_TXT) " +
                    " VALUES (:parmStorageId, :parmApplId, :parmTaskId, :parmTypeId, :ParmValTxt, :parmBlob)";
                cmd.Parameters.Add("parmStorageId", "CDP.STRG_ID_SEQ.nextval");
                cmd.Parameters.Add("parmApplId", appId);
                cmd.Parameters.Add("parmTaskId", taskId);
                cmd.Parameters.Add("parmTypeId", parmTypeId);
                cmd.Parameters.Add("ParmValTxt", parmValue);
                OracleParameter param = cmd.Parameters.Add("parmBlob", OracleDbType.Blob); //Add the parameter for the blobcolumn
                string tim = "this is some very large string 42k characters";
           //     byte[] bytes = new byte[tim.ToCharArray().Length * sizeof(char)];

                byte[] bytes = System.Text.Encoding.UTF8.GetBytes(tim);

                System.Buffer.BlockCopy(tim.ToCharArray(), 0, bytes, 0, bytes.Length);
                param.Value = bytes; //Asign the Byte Array to the parameter
                cmd.ExecuteNonQuery();
            }
            connection.Close();
        }
    }
    catch (Exception ex)
    {
        Log.Error(ex);
        return false;
    }

这给了我以下错误。

Oracle.DataAccess.Client.OracleException ORA-01722: invalid number    at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck, Int32 isRecoverable)
   at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, Boolean bCheck)
   at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
   at SeasonsSvc.Models.SeasonsOracleRepository.BlobInsert(Int32 appId, Int32 taskId, Int32 parmTypeId, String parmValue, SeasonsReturnData myDataSet) in c:'Users'e048014'Documents'Visual Studio 2012'Projects'SeasonsSvc'SeasonsSvc'Models'SeasonsOracleRepository.cs:line 174

然后我尝试了以下方法:

 public bool BlobInsert(int appId, int taskId, int parmTypeId, string parmValue, SeasonsReturnData myDataSet)
        {
            var connection = _dataUtility.GetOracleConnection("OracleConn");
            StringBuilder sb = new StringBuilder();
            var serializer = new JavaScriptSerializer();
           serializer.Serialize(myDataSet,sb);
               try
               {
                   using (connection)
                   {
                       using (var cmd = connection.CreateCommand())
                       {
                           cmd.CommandType = CommandType.Text;
                           cmd.BindByName = true;
                           cmd.CommandText =
                               "INSERT INTO STORAGE (STRG_ID, APPL_ID, TASK_ID, PARM_TYPE_ID, PARM_VAL_TXT,APPL_ITEM_TXT) " +
                               " VALUES (STRG_ID_SEQ.nextval,2, 1, 1, 'cows', :parmBlob)";
                           cmd.Parameters.Add("parmBlob", "utl_raw.cast_to_raw('" + sb.ToString() + "')");
                           cmd.ExecuteNonQuery();
                       }
                       connection.Close();
                   }
               }
               catch (Exception ex)
               {
                   Log.Error(ex);
                   return false;
               }  
           return true;
        }

这给了我以下错误:

{Oracle.DataAccess.Client.OracleException ORA-01461: can bind a LONG value only for insert into a LONG column    at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck, Int32 isRecoverable)
   at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, Boolean bCheck)
   at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
   at SeasonsSvc.Models.SeasonsOracleRepository.BlobInsert(Int32 appId, Int32 taskId, Int32 parmTypeId, String parmValue, SeasonsReturnData myDataSet) in c:'Users'e048014'Documents'Visual Studio 2012'Projects'SeasonsSvc'SeasonsSvc'Models'SeasonsOracleRepository.cs:line 118}

我被卡住了,我可以让utl_raw.cast_to_raw("some string")在Toad中的上述insert语句中工作,但如果我在"some字符串"的位置复制json,我在Toad和Visual Studio中都会收到一个错误,说字符串太长。我想这是4000个字符的限制,这就是我试图绑定变量的原因。

感谢您的帮助、想法等。。。

正在将字符串数据插入blob

ORA-01722: invalid number与BLOB列无关,而是与传递parmStorageId参数的方式有关。你应该像下面的C#代码一样直接将其移动到CommandText中(这个解决方案对我有效,我还删除了System.Buffer.BlockCopy ...行)

using (var cmd = connection.CreateCommand())
{
    cmd.CommandType = CommandType.Text;
    cmd.BindByName = true;
    cmd.CommandText =
        "INSERT INTO STORAGE (STRG_ID, APPL_ID, TASK_ID, PARM_TYPE_ID, PARM_VAL_TXT,APPL_ITEM_TXT) " +
        " VALUES (STRG_ID_SEQ.nextval, :parmApplId, :parmTaskId, :parmTypeId, :ParmValTxt, :parmBlob)";
    cmd.Parameters.Add("parmApplId", appId);
    cmd.Parameters.Add("parmTaskId", taskId);
    cmd.Parameters.Add("parmTypeId", parmTypeId);
    cmd.Parameters.Add("ParmValTxt", parmValue);
    OracleParameter param = cmd.Parameters.Add("parmBlob", OracleDbType.Blob); 
    string tim = "this is some very large string 42k characters";
    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(tim);
    param.Value = bytes; 
    cmd.ExecuteNonQuery();
}

填充像strg_id这样的字段最常见的方法是使用触发器,在您的情况下,您可以创建这个触发器:

create or replace trigger strg_id_trg 
before insert on storage  
for each row
begin
  :new.strg_id := strg_id_seq.nextval;
end strg_id_trg;

忘记在代码中填充这些数据。此外,请考虑将您的BLOB字段更改为CLOB,就像在评论中已经建议的那样。BLOB是为二进制数据、图像、音频等设计的。