本文介绍了K/3 Cloud如何为物理表格生成主键流水号的方法。K/3 Cloud为每个物理表建立索引辅助表,通过插入并获取该表的自动增长Id作为流水号,之后清空辅助表。插件通过调用服务获取流水号。同时,文章还对比了K/3 Cloud与K/3 Wise在流水号生成机制上的差异,指出K/3 Wise存在性能瓶颈问题。
问题背景
经常看到有伙伴咨询,需要手工向K/3 Cloud的物理表格中插入数据,但不知道如何生成表格主键值。
或者自行获取表格当前最大主键值+1,作为新的主键值:
这样插入的数据本身不会出现问题,但是用户从K/3 Cloud中手工新增单据保存时,即会因为主键重复而保存失败。
被问的多了,感觉有必要开个专贴,再有新伙伴咨询时,即可奉上此贴。
K/3 Cloud是如何为表格产生流水号的?
K/3 Cloud 为每个物理表格(t_xxx),都建立了一个索引辅助表(z_xxx),内含一个自动增长的Id字段,以及一个无意义的整数字段Column1。
在向表格(t_xxx)插入数据之前,先向其索引辅助表(z_xxx),插入1行数据,利用自动增长的Id字段,产生一个流水号作为表格主键。
随后,会清空索引辅助表,保持空行。
普通的物理表格,其索引辅助表的命名规则,是把表格的前缀"t_",替换为"z_",如"t_Bas_Item"表的索引辅助表为"z_Bas_Item"。
如果表格的前缀不是"t_",则直接在表名前添加"z_"作为索引辅助表,如"JD_t_Cust_Entry100001"的索引辅助表为"Z_JD_t_Cust_Entry100001"
例外:各种基础资料的主表(仅主表),采用同一个索引辅助表(z_bas_item),以便产生统一的流水号,如供应商、客户、员工,部门的主表,其内码是统一分配、互不重复的。
K/3 Cloud插件如何为表格产生流水号?
K/3 Cloud封装了一个服务 (Kingdee.BOS.ServiceHelper.DBServiceHelper.GetSequenceInt64),产生表格的流水号。
插件直接调用此服务即可。
示例代码如下:
//***********************************************
/// <summary>
/// 把图片数据,直接存入到数据库表格中
/// </summary>
private void SaveFileToDB()
{
// 获取表格名称
string tableName = this.View.BillBusinessInfo.Entrys[0].TableName;
// 表格主键字段名
string pkFieldName = this.View.BillBusinessInfo.GetForm().PkFieldName;
// 图片字段名(Image类型)
string imageFieldName = "F_JD_Picture";
// SQL语句
string sql = string.Format("INSERT INTO {0} ({1}, {2}, {3}) Values (@FID, @FBillNo, @Image)",
tableName,
pkFieldName,
this.View.BillBusinessInfo.GetBillNoField().FieldName,
imageFieldName);
// 准备字段值:
// 获取主键值
var ids = Kingdee.BOS.ServiceHelper.DBServiceHelper.GetSequenceInt64(this.Context,
tableName,
1);
// 图片内容
Byte[] fileValue = this.ReadFile(this._fullFileName);
// 准备SQL参数
List<SqlParam> paramList = new List<SqlParam>();
paramList.Add(new SqlParam("@FID", KDDbType.Int64, ids.ElementAt(0)));
paramList.Add(new SqlParam("@FBillNo", KDDbType.String, "JD" + Convert.ToString(ids.ElementAt(0))));
// 使用KDDbType.Binary类型可行,测试图片能够存入(测试图片2,280K)
paramList.Add(new SqlParam("@Image", KDDbType.Binary, fileValue));
DBServiceHelper.Execute(this.Context, sql, paramList);
}
//******************************************
存储过程中,如何为表格产生流水号?
我们不推荐使用存储过程插入表格数据,但必须时,请使用如下示例代码,产生表格流水号:
declare @id int
insert into z_bas_item (column1) values (1)
select @id = id from z_bas_item
delete from z_bas_item
select @id
与K/3 Wise的差异?
K/3 Wise有一个单独的物理表格(表名我不记得了),记录各个表的当前最大流水号,插入各种表格数据前,都要读取此表格的数据并更新。
并发业务量大时,会有性能瓶颈。
K/3 Cloud则是为各个表格单独建立索引辅助表,不易形成性能瓶颈。
推荐阅读