Хранимая процедура для вставки двух таблиц с отношением - PullRequest
4 голосов
/ 23 апреля 2011

Я пытался вставить новую строку в две таблицы, которые связаны между собой.Я написал хранимую процедуру следующим образом.

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».Оператор был расторгнут.

Я новичок в хранимых процедурах, поэтому есть предложения, как мне исправить это, чтобы я мог вставить данные в две таблицы?

TABLEСХЕМА

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)

Ответы [ 3 ]

6 голосов
/ 23 апреля 2011

@ Ричард Это «идентификатор», который является автоматическим увеличением в обеих таблицах.

Хорошо использовать автоинкремент (IDENTITY) в качестве первичного ключа, но использовать его в качестве внешнего ключа опасно, поскольку вы не можете гарантировать, что они всегда будут синхронизированы; любой откат может привести к их поломке (откат не отменяет приращения идентификатора, так как это повлияет на другие идентификаторы SPID). Кроме того, любая гонка между двумя одновременными INSERT s будет в опасности.

Правильный подход здесь - запросить SCOPE_IDENTITY() после первой вставки и использовать его в INSERT для второй таблицы; во второй таблице вы говорите это значение. Обратите внимание, что, поскольку @@ERROR и SCOPE_IDENTITY() являются плавающими значениями, вы должны запрашивать их оба сразу после первого INSERT:

SELECT @Error = @@ERROR, @NewId = SCOPE_IDENTITY()
1 голос
/ 23 апреля 2011

Вам нужно захватить автоматически увеличенное значение, которое вы получаете, когда вставляете в первую таблицу 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 
0 голосов
/ 23 апреля 2011
Create Table tbl_user_login
(
**ID INT Identity(1,1),**
UserID varchar10,
Pass varchar50 ,
Enabled int,
Permission int ,
Rank int
);

Сделать столбец идентификатора идентификатором (1,1), который будет автоматически увеличиваться и который решит вашу проблему.Сделайте это в обеих таблицах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...