NHibernate+Oracle 遇到ORA-01461和ORA-01084及解决方法
2010-03-13 20:10 无常 阅读(3132) 评论(0) 编辑 收藏 举报如果使用到Oracle的CLOB字段,那么NHibernate会遇到很诡异的“ORA-01461:仅可以插入LONG列的LONG值赋值”错误。关于此错误的分析和解决方法在这里(http://blog.csdn.net/pojianbing/archive/2008/08/09/2789426.aspx)有详细的介绍,实现NHibernate的自定义类型IUserType接口 :
public abstract class PatchForOracleLobField : IUserType { public PatchForOracleLobField() { } public bool IsMutable { get { return true; } } public System.Type ReturnedType { get { return typeof(String); } } public SqlType[] SqlTypes { get { return new SqlType[] { NHibernateUtil.String.SqlType }; } } public object DeepCopy(object value) { return value; } public new bool Equals(object x, object y) { return x == y; } public int GetHashCode(object x) { return x.GetHashCode(); } public object Assemble(object cached, object owner) { return DeepCopy(cached); } public object Disassemble(object value) { return DeepCopy(value); } public object NullSafeGet(IDataReader rs, string[] names, object owner) { return NHibernate.NHibernateUtil.StringClob.NullSafeGet(rs, names[0]); } public abstract void NullSafeSet(IDbCommand cmd, object value, int index); public object Replace(object original, object target, object owner) { return original; } } public class OracleClobField : PatchForOracleLobField { public override void NullSafeSet(IDbCommand cmd, object value, int index) { if (cmd is OracleCommand) { //CLob、NClob类型的字段,存入中文时参数的OracleDbType必须设置为OracleDbType.Clob //否则会变成乱码(Oracle 10g client环境) OracleParameter param = cmd.Parameters[index] as OracleParameter; if (param != null) { param.OracleType = OracleType.Clob;// 关键就这里啦 param.IsNullable = true; } } NHibernate.NHibernateUtil.StringClob.NullSafeSet(cmd, value, index); } }
用此方法解决了CLOB字段2000-4000字的问题,可是今天又遇到了个新的“ORA-01084: OCI 调用中的参数无效”错误,google了一下,大概是说CLOB字段如果为null或’’时就会出这个错。
解决的办法:
将OracleClobField.NullSafeSet中的
if (cmd is OracleCommand) ….
改为
if ((cmd is OracleCommand) && !string.IsNullOrEmpty(value as string))
如果值是空或者空字符串的话就让NHibernate当默认的varchar2处理。
from:http://wuchang.cnblogs.com