我试图在两个表之间插入一个新行。我按如下方式编写了存储过程。
ALTER PROCEDURE InsertUserProfile
(
@UserID varchar(10),
@Pass varchar(50),
@Enabled int,
@Permission int,
@Rank int,
@FName varchar(50),
@LName varchar(50),
@Phone varchar(50),
@Email1 varchar(50),
@Email2 varchar(50)
)
AS
BEGIN TRANSACTION
INSERT INTO tbl_user_login VALUES (@UserID, @Pass, @Enabled, @Permission, @Rank)
IF @@ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
INSERT INTO tbl_user_profile VALUES (@FName, @LName, @Phone, @Email1, @Email2)
IF @@ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
COMMIT
从此处遵循ASP.NET代码
SqlConnection sqlConn = new SqlConnection(ConfigurationManager.ConnectionStrings["DBConnString"].ConnectionString);
SqlCommand cmd = new SqlCommand("dbo.InsertUserProfile", sqlConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@UserID", DbType.String).Value = txtUserID.Text;
cmd.Parameters.Add("@Pass", DbType.String).Value = txtPass.Text;
cmd.Parameters.Add("@Enabled", DbType.Int32).Value = 1;
cmd.Parameters.Add("@Permission", DbType.Int32).Value = Convert.ToInt32(ddlPermission.SelectedValue);
cmd.Parameters.Add("@Rank", DbType.Int32).Value = Convert.ToInt32(ddlRank.SelectedValue);
cmd.Parameters.Add("@FName", DbType.String).Value = txtFName.Text;
cmd.Parameters.Add("@LName", DbType.String).Value = txtLName.Text;
cmd.Parameters.Add("@Phone", DbType.String).Value = txtPhone.Text;
cmd.Parameters.Add("@Email1", DbType.String).Value = txtEmail1.Text;
cmd.Parameters.Add("@Email2", DbType.String).Value = txtEmail2.Text;
sqlConn.Open();
int rows = cmd.ExecuteNonQuery();
sqlConn.Close();
但是我收到了以下错误。
INSERT语句与之冲突 FOREIGN KEY约束 “FK_tbl_user_profile_tbl_user_login”。 冲突发生在数据库“我的 数据库位置“,表格 “dbo.tbl_user_login”,列“ID”。该 声明已被终止。
我是Stored Procedures的新手,所以我应该如何修复它以便我可以将数据插入两个表中?
TABLE SCHEMA
tbl_user_login
ID (int)
UserID (varchar10)
Pass (varchar50)
Enabled (int)
Permission (int)
Rank (int)
tbl_user_profile
ID (int)
FName (varchar50)
LName (varchar50)
Phone (varchar50)
Email1 (varchar50)
Email2 (varchar50)
答案 0 :(得分:6)
@Richard它的“ID”是两个表中的自动增量。
将自动增量(IDENTITY
)作为主键是可以的,但将其用作外键是危险的,因为您无法保证它们始终保持同步;任何回滚都可能使它们断开(回滚不会撤消身份增量,因为这会影响其他SPID)。此外,两个并发INSERT
之间的任何线程竞争都将处于危险之中。
这里的正确方法是在第一次插入后查询SCOPE_IDENTITY()
,并在INSERT
到第二个表中使用它;即在第二个表格中,您告诉它的值。请注意,由于@@ERROR
和SCOPE_IDENTITY()
是浮动值,因此您应该在第一个INSERT
之后直接查询它们:
SELECT @Error = @@ERROR, @NewId = SCOPE_IDENTITY()
答案 1 :(得分:1)
您需要捕获插入第一个表tbl_user_login时获得的自动递增值。捕获后,您需要使用它插入第二个表。
DECLARE @ID int
BEGIN TRANSACTION
INSERT INTO tbl_user_login VALUES (@UserID, @Pass, @Enabled, @Permission, @Rank)
SET @ID = SCOPE_IDENTITY()
IF @@ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
INSERT INTO tbl_user_profile VALUES (@ID, @FName, @LName, @Phone, @Email1, @Email2)
IF @@ERROR <> 0
BEGIN
ROLLBACK
RETURN
END
COMMIT
答案 2 :(得分:-1)
Create Table tbl_user_login
(
**ID INT Identity(1,1),**
UserID varchar10,
Pass varchar50 ,
Enabled int,
Permission int ,
Rank int
);
将ID列设置为Identity(1,1),它将是自动递增列,这将解决您的问题。在两个表格中进行。