将字符串数据插入blob

时间:2015-06-26 20:48:05

标签: c# oracle blob

您好我在尝试使用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

字符串数据将是大约42k json文件,但是目前我甚至无法获得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}

我被卡住了,我可以在Toad的上面插入语句中使用 utl_raw.cast_to_raw('some string'),但是如果我将json复制到“some”的位置字符串“我在Toad和Visual Studio中都收到错误,表示字符串太长。我猜这是4000个字符的限制,这就是我试图绑定变量的原因。

感谢任何帮助,想法,等等......

1 个答案:

答案 0 :(得分:0)

ORA-01722: invalid number与您的BLOB列无关,但与您传递parmStorageId参数的方式无关。 您应该将其直接移动到CommandText中,就像下面的C#代码一样(此解决方案对我有效,我也删除了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专为二进制数据,图像,音频等而设计。