主从表添加记录,有没有标准解决方案?100分

cbuiler 2003-01-09 10:24:48
用ASP.NET开发,使用SQLServer 2000数据库,遇到一个问题,也是以前在Delphi开发中遇到过的:
有一个主表和一个从表,主表中的Key是一个Identity流水号,现在我在同时输入好了主表和从表中要添加的记录,当我往数据库中添加时,应该先添加主表中的记录,但我如何能得到主表添加后的流水号,用来再添加从表的记录?
我想大家肯定都遇到够类似的问题,有没有标准的解决方案,多谢!
...全文
91 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
cbuiler 2003-01-13
  • 打赏
  • 举报
回复
谢谢,就用你的办法了!给分了
ykn 2003-01-09
  • 打赏
  • 举报
回复
锁定数据库怎么了,只是提交时候才锁定的啊。比起你用存储过程要方便的多了呀。
allanli 2003-01-09
  • 打赏
  • 举报
回复
用stored procedure
BEGIN TRAN T1
INSERT INTO table(...) VALUES (...)
SELECT @@IDENTITY AS 'Identity'
COMMIT TRAN T1
你可以把Identity作为参数返回就可以了
cbuiler 2003-01-09
  • 打赏
  • 举报
回复
to ykn:
你的办法也需要锁定数据库,不然也会导致加入相同值的记录
cbuiler 2003-01-09
  • 打赏
  • 举报
回复
to Goldsunline:
你的办法也不行,你是在添加后,又把最大值取出来,这时有可能最大值不是你添加过了记录,因为可能有其他用户又往表中添加过新的记录了,除非你锁定数据库。
cbuiler 2003-01-09
  • 打赏
  • 举报
回复
这个办法恐怕不行,你是另外建立了一个Unique的字段去索引identity字段。有没有办法在主表添加记录的同时把添加后的Identity字段值取出?
ykn 2003-01-09
  • 打赏
  • 举报
回复
这样的问题换一个方式解决不是更好吗?〉
你为什么不可以把自动流水号(也应该是你的主表的主键)设为人工自动加1,然后用事务保存就可以了。这样,流水号不是由你控制了吗。
我们的项目都是这样做的。
Lancer903 2003-01-09
  • 打赏
  • 举报
回复
fcsUserDivision是主表
fcsUserDivisionDetails是从表
UserDivisionalID 是流水号主键
你可以看看是不是有用!
Lancer903 2003-01-09
  • 打赏
  • 举报
回复
在stored procedure中处理:
BEGIN TRAN T1
Insert into fcsUserDivision (IsObsolete) values (@IsObsolete)
select @UserDivisionalID = max(UserDivisionalID) from fcsUserDivision
Insert into fcsUserDivisionDetails (UserDivisionalID, LangCode, UserDivision, UserDepartment, UserSection) values (@UserDivisionalID, @LangCode, @UserDivision, @UserDepartment, @UserSection)
COMMIT TRAN T1
kinglht 2003-01-09
  • 打赏
  • 举报
回复
希望你有耐心看完,也希望对你有帮助!!:)
kinglht 2003-01-09
  • 打赏
  • 举报
回复
//使用事务处理同时更新两个表:
string CreateNewCustUser(ref CustomerDataset customerDS)
{
DbComponent com = new DbComponent();
OleDbTransaction trans=null;
try
{
com.dbCnc.Open();
//使用事务处理
trans=com.dbCnc.BeginTransaction();
com.daCust.InsertCommand.Transaction=trans;
com.daCust.UpdateCommand.Transaction=trans;
com.daUser.InsertCommand.Transaction=trans;
com.daUser.UpdateCommand.Transaction=trans;
com.daCust.Update(customerDS.CUST);
com.daUser.Update(customerDS.USERS);
trans.Commit();
}
catch (OleDbException e)
{
//如果未能实现两个表同时修改
if(trans!=null)
{
trans.Rollback();
// customerDS.Clear();
}
//如果存在相同主键的记录,返回"EXIST"
if (e.ErrorCode == -2147217873)
return "EXIST";
else
return e.Message;
}
catch(Exception e)
{
return e.Message;
}
finally
{
com.dbCnc.Close();
}
return "OK";
}
kinglht 2003-01-09
  • 打赏
  • 举报
回复
//从Identity表(两个字段:idName,idValue)中取ID(key)
string GetIdentity(string idName,out string idValue)
{
idValue="";
DbComponent com=new DbComponent();
OleDbTransaction trans=null;
try
{
com.dbCnc.Open();
trans=com.dbCnc.BeginTransaction();
OleDbCommand oleDbCommand1 = new OleDbCommand();
oleDbCommand1.Connection = com.dbCnc;
oleDbCommand1.Transaction = trans;

oleDbCommand1.CommandText = "UPDATE [IDENTITY] SET ID_VALUE = CONVERT(VARCHAR,CONVERT(BIGINT,ID_VALUE) + 1) WHERE ID_NAME = ? ; SELECT ID_VALUE FROM [IDENTITY] WHERE ID_NAME = ?";
oleDbCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("ID_NAME", System.Data.OleDb.OleDbType.VarChar, 50, "ID_NAME"));
oleDbCommand1.Parameters.Add(new System.Data.OleDb.OleDbParameter("ID_NAME2", System.Data.OleDb.OleDbType.VarChar, 50, "ID_NAME2"));

oleDbCommand1.Parameters["ID_NAME"].Value = idName;
oleDbCommand1.Parameters["ID_NAME2"].Value = idName;

OleDbDataReader dr = oleDbCommand1.ExecuteReader();
if(dr.Read())
{
Int64 icust_id = Int64.Parse(dr.GetString(0)) - 1;
idValue = string.Format("{0:d10}", icust_id);
dr.Close();
}
else
{
dr.Close();

OleDbCommand oleDbCommand2 = new OleDbCommand();
oleDbCommand2.Connection = com.dbCnc;
oleDbCommand2.Transaction = trans;

oleDbCommand2.CommandText = "INSERT INTO [IDENTITY](ID_NAME,ID_VALUE) VALUES(?,?); INSERT INTO [IDENTITY](ID_NAME,ID_VALUE) VALUES(?,?)";
oleDbCommand2.Parameters.Add(new System.Data.OleDb.OleDbParameter("ID_NAME", System.Data.OleDb.OleDbType.VarChar, 50, "ID_NAME"));
oleDbCommand2.Parameters.Add(new System.Data.OleDb.OleDbParameter("ID_VALUE", System.Data.OleDb.OleDbType.VarChar, 100, "ID_VALUE"));
oleDbCommand2.Parameters.Add(new System.Data.OleDb.OleDbParameter("ID_NAME2", System.Data.OleDb.OleDbType.VarChar, 50, "ID_NAME2"));
oleDbCommand2.Parameters.Add(new System.Data.OleDb.OleDbParameter("ID_VALUE2", System.Data.OleDb.OleDbType.VarChar, 100, "ID_VALUE2"));
oleDbCommand2.Parameters["ID_NAME"].Value = idName;
oleDbCommand2.Parameters["ID_VALUE"].Value = "0000000001";
oleDbCommand2.Parameters["ID_NAME2"].Value = idName;
oleDbCommand2.Parameters["ID_VALUE2"].Value = "0000000002";

idValue = "0000000001";
oleDbCommand2.ExecuteNonQuery();
}
trans.Commit();
}
catch(Exception e)
{
if(trans!=null)
{
trans.Rollback();
}
return e.Message;
}
finally
{
com.dbCnc.Close();
}
return "OK";

}
ripple_yi 2003-01-09
  • 打赏
  • 举报
回复
标准的解决方案我不知道。这是我想的方法。
新插入的纪录identity流水号肯定是最大的,你可以用select max(identity字段名)...来取最大值,肯定就是新加的纪录。
kinglht 2003-01-09
  • 打赏
  • 举报
回复
主表:"CUST",从表:"USERS";
//主表
CustomerDataset.CUSTRow row = customerDS.CUST.NewCUSTRow();

//初始值
row.CUST_ID = "";//key
row.BALANCE = 0;
row.CREATED_DATE = DateTime.Now;
row.CUST_STATUS = "E";

row.CUST_TYPE = dropCustType.SelectedItem.Value;
row.DOMAIN_NAME = txtDomainName.Text;
row.CUST_NAME = txtCustName.Text;
row.CUST_IDENTITY = txtCustIdentity.Text;
row.CUST_ADDRESS = txtCustAddress.Text;
row.CONTACT_NAME = txtContactName.Text;
row.CONTACT_PHONE = txtContactPhone.Text;
row.BANK_ID = dropBank.SelectedItem.Value;
row.BANK_ACCOUNT = txtAccount.Text;
customerDS.CUST.AddCUSTRow(row);
Session["cnc.Hoten.Boss.CustinfoWeb.CustReg.CustReg.CustDS"]=customerDS;
//从
CustomerDataset customerDS =(CustomerDataset)Session["cnc.Hoten.Boss.CustinfoWeb.CustReg.CustReg.CustDS"];
string userID=txtUserID.Text;
string commonName=txtCommonName.Text;
string userPassword=txtUserPassword.Text;
string idValue="";
GetIdentity("CUST_ID",out idValue);
CustomerDataset.CUSTRow cRow = (CustomerDataset.CUSTRow)customerDS.CUST.Rows[0];
cRow.CUST_ID = idValue;
CustomerDataset.USERSRow row = customerDS.USERS.NewUSERSRow();
row.CUST_ID=idValue;
row.USER_ID=userID;
row.USER_PASSWORD=userPassword;
row.COMMON_NAME=commonName;
customerDS.USERS.AddUSERSRow(row);
//主从一起更新
CreateNewCustUser(ref customerDS);
mmkk 2003-01-09
  • 打赏
  • 举报
回复
Get @@IDENTITY Value,that's OK!
而且最好能使用一个事务来控制
cbuiler 2003-01-09
  • 打赏
  • 举报
回复
不懂
ZHANG9652 2003-01-09
  • 打赏
  • 举报
回复
天,自己写公用控件来搞定好了
kinglht 2003-01-09
  • 打赏
  • 举报
回复
用我的方法,Identity表里永远存的是最大值(可用ID),得的时候先把改值加1,可避免两个人同时更新时的冲突;这样还有个好处就是即使删除某一记录,再插入的时候也不会出现主健重复的现象!不要看代码多就懒得看!

62,261

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧