正在将字符串数据插入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个字符的限制,这就是我试图绑定变量的原因。
感谢您的帮助、想法等。。。
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是为二进制数据、图像、音频等设计的。