C# Oracle 之Insert 与 Update 的封装

最近在写一个Asp.net 的框架,在本地搭建了数据缓存,采用了 定时的lazy fresh的过期方式,

但是大量的数据其实是没有改变的,改变的只是很小的部分,这个时候缓存过期,全部重新刷新数据就显得非常浪费了。

思来想去,觉得我可以从数据库的更新方法下手,于是有了下面这些尝试了。

在Oracle 中Insert 语句是可以使用 returning 返回新增的记录的。

于是我们的Insert 语句就是这样了.

INSERT INTO TableName (UniqueColumn,OtherColumns)
VALUES(Table_SEQ.Nextval,Values) RETURNING UniqueColumn INTO :Unique_Id。

这样执行之后,我就可以通过Out参数 Unique_Id 获取新增的记录的主键啦。

附C#:

public override object Insert(EditorParams pm)
        {
            if (pm != null && pm.EditValues.Count > 0)
            {
                QuerySetting qs = ConfigEnginer.Instance.DataModels[pm.ModelType];
                string insertformart = @"INSERT INTO #OysterVal:TableName# (#OysterVal:UniqueColumn#,#OysterVal:Columns#)
VALUES(#OysterVal:TableName#_SEQ.Nextval,#OysterVal:Values#) RETURNING #OysterVal:UniqueColumn# INTO :Unique_Id";

                Dictionary<string, string> vals = new Dictionary<string, string>();
                List<IDataParameter> parms = new List<IDataParameter>();

                vals.Add("TableName", qs.TableName);
                vals.Add("UniqueColumn", qs.UniqueColumn.ColumnName);
                vals.Add("Columns", pm.InsertColumns);
                vals.Add("Values", pm.InsertValues);

                //System.Nullable
                var Unqtype = qs.UniqueColumn.PropertyType;
                if (Unqtype.FullName.Contains("System.Nullable"))
                {
                    var types = Unqtype.GetGenericArguments();
                    if (types != null && types.Length > 0)
                    {
                        Unqtype = types[0];
                    }
                }

                var pr = new OracleParameter(":Unique_Id", Activator.CreateInstance(Unqtype));
                pr.Direction = ParameterDirection.InputOutput;
                parms.Add(pr);
                parms.AddRange(pm.DataParms);

                string sql = insertformart.ToOysterTemplate(vals);
                pm.EffectCount = DbEnginer.Instance.ExecuteNonQuery(sql, parms.ToArray());
                pm.EffectUniqueIds.Add(pr.Value);
                return pm.EffectUniqueIds[0];
            }
            else
            {
                throw new Exception("请检查传入的EditParams,更新列数据不能为空!");
            }

            return null;
        }

仅供参考,里面使用到的其他类型引用,以后会慢慢分享。

而UPDATE 则可以这样:SELECT UniqueColumn FROM TableName WHERE Condition FOR UPDATE。

将要更新的行Select 出来,并且加上Update 的锁。保证Update按顺序执行,而不会错乱。

附C#代码:

public override int Update(EditorParams pm)
        {
            if (pm != null && pm.EditValues.Count > 0)
            {
                try
                {
                    QuerySetting qs = ConfigEnginer.Instance.DataModels[pm.ModelType];
                    string selectforupdatestr = "SELECT #OysterVal:UniqueColumn# FROM #OysterVal:TableName# WHERE #OysterVal:Condition# FOR UPDATE";
                    List<IDataParameter> parms = new List<IDataParameter>();
                    string cond = pm.condition.ToString(parms);

                    Dictionary<string, string> dic = new Dictionary<string, string>();
                    dic.Add("UniqueColumn", qs.UniqueColumn.ColumnName);
                    dic.Add("TableName", qs.TableName);
                    dic.Add("Condition", cond);

                    string selectsql = selectforupdatestr.ToOysterTemplate(dic);
                    DbEnginer.Instance.DbConnection.IsReaderReading = true;
                    var ds = DbEnginer.Instance.ExecuteQuery(selectsql, parms);
                    if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
                    {
                        dic.Add("Columns", pm.UpdateColumns);
                        List<object> ids = new List<object>();
                        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                        {
                            if (!ds.Tables[0].Rows[i][0].Equals(DBNull.Value))
                            {
                                ids.Add(ds.Tables[0].Rows[i][0]);
                            }
                            if ((i > 0 && i % 999 == 0) || i == ds.Tables[0].Rows.Count - 1)
                            {
                                var condition = Condition.New(qs.ClassType, qs.UniqueColumn.Property, ConditionOperator.In, ids);
                                parms = new List<IDataParameter>();
                                cond = condition.ToString(parms);
                                dic["Condition"] = cond;
                                string updatestr = "UPDATE #OysterVal:TableName# SET #OysterVal:Columns# WHERE #OysterVal:Condition#";
                                string updatesql = updatestr.ToOysterTemplate(dic);
                                foreach (var p in pm.DataParms)
                                {
                                    var temp = DbEnginer.Instance.NewDataParameter(p.ParameterName);
                                    temp.ParameterName = p.ParameterName;
                                    temp.DbType = p.DbType;
                                    temp.Direction = p.Direction;
                                    temp.Value = p.Value;
                                    parms.Add(temp);
                                }
                                pm.EffectCount += DbEnginer.Instance.ExecuteNonQuery(updatesql, parms);
                                pm.EffectUniqueIds.AddRange(ids);
                                ids.Clear();
                            }
                        }
                        DbEnginer.Instance.ExecuteNonQuery("commit");
                    }
                }
                catch (Exception ex)
                {
                    DbEnginer.Instance.ExecuteNonQuery("rollback");
                    throw ex;
                }
                finally
                {
                    DbEnginer.Instance.DbConnection.IsReaderReading = false;
                    DbEnginer.Instance.DbConnection.Close();
                }
            }
            else
            {
                throw new Exception("请检查传入的EditParams,更新列不能为空!");
            }
            return pm.EffectCount;
        }

哈哈,先就这样吧,只是分享一个思路,不过这样的效率不是很好。10000条Insert 12秒,Update 4秒,谢谢大家。

posted on 2011-04-14 21:02  oyster.oy  阅读(4750)  评论(12编辑  收藏  举报

导航