SQL Ошибка сервера в c# строке или двоичные данные будут усечены. вставить оператор конфликта с внешним ключом - PullRequest
0 голосов
/ 12 апреля 2020
create table [User]
(
    userId int IDENTITY(1,1) primary key ,
    UserName nvarchar(30) unique,
    gender nvarchar(2),
    check( gender in ('M','F')),
    email nvarchar(40),
    DOB date
)

create table User_Auth
(
    uName nvarchar(30),
        foreign key (uName) references [User](UserName),
    pass nvarchar(30)
)

ALTER PROCEDURE [dbo].[CHECKREGISTERCREDENTIALSFORUSER]
    @USRNAME NVARCHAR(30),
    @DATE_OF_BIRTH DATE,
    @EMAIL NVARCHAR(50),
    @PASSWORD NVARCHAR(50),
    @GENDER NVARCHAR(5),
    @enterflag int output
AS
BEGIN
    SET @enterflag = 0;

    IF NOT EXISTS (SELECT UserName FROM [User] u WHERE u.UserName = @USRNAME)
    BEGIN
        IF (@DATE_OF_BIRTH <= GETDATE())
        BEGIN
            INSERT INTO [User] (UserName, gender, email, DOB) 
            VALUES (@USRNAME, @GENDER, @EMAIL, @DATE_OF_BIRTH)

            INSERT INTO [User_Auth] (uName, pass) 
            VALUES (@USRNAME, @PASSWORD)

            SET @enterflag = 1;
        END
        ELSE
        BEGIN
            PRINT 'invalid birth date entered';
        END
    END
    ELSE
    BEGIN
        PRINT 'username is taken';
    END
END

public static int Signup(string uname, string password, DateTime DOB, string email, string genders)
{
    SqlConnection con = new SqlConnection(connectionString);
    con.Open();

    SqlCommand cmd;
    int result = 0;

    try
    {
        if (con != null && con.State == ConnectionState.Open)
        {
            cmd = new SqlCommand("CHECKREGISTERCREDENTIALSFORUSER", con);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            cmd.Parameters.Add("@USRNAME", SqlDbType.NVarChar, 30).Value = uname;
            cmd.Parameters.Add("@PASSWORD", SqlDbType.NVarChar, 50).Value = password;
            cmd.Parameters.Add("@DATE_OF_BIRTH", SqlDbType.Date).Value = DOB;
            cmd.Parameters.Add("@GENDER", SqlDbType.NVarChar, 5).Value = email;
            cmd.Parameters.Add("@EMAIL", SqlDbType.NVarChar, 50).Value = genders;
            cmd.Parameters.Add("@enterflag", SqlDbType.Int).Direction = ParameterDirection.Output;

            cmd.ExecuteNonQuery();

            result = Convert.ToInt32(cmd.Parameters["@enterflag"].Value);
        }
    }
    catch (SqlException ex)
    {
        Console.WriteLine("SQL Error" + ex.Message.ToString());
        result = -1; //-1 will be interpreted as "error while connecting with the database."
    }
    finally
    {
        con.Close();
    }

    return result;
}

Вот код C# - я не могу понять, что не так - я получаю ошибку. В параметрах процедуры отсутствует вход за пределы. Размер параметров в хранимой процедуре такой же, как написано в коде. Предполагается вернуть 1, если регистрация прошла успешно. Более того, в моей процедуре я добавляю в родительскую таблицу, а затем в дочернюю таблицу, но все равно получаю ошибку

Конфликт вставки оператора с ограничением внешнего ключа

1 Ответ

1 голос
/ 12 апреля 2020

Значения email и gender смешиваются при настройке параметров, поэтому вы фактически устанавливаете значение email в gender в базе данных и наоборот.

cmd.Parameters.Add("@GENDER", SqlDbType.NVarChar, 5).Value = email;
cmd.Parameters.Add("@EMAIL", SqlDbType.NVarChar, 50).Value = genders;

должно быть

cmd.Parameters.Add("@GENDER", SqlDbType.NVarChar, 5).Value = genders;
cmd.Parameters.Add("@EMAIL", SqlDbType.NVarChar, 50).Value = email;

Кроме того, в таблице User gender определено с длиной 2, но в хранимой процедуре объявлена ​​длина 5. Тем не менее, вы используете check (gender in ('M', 'F')) это один символ.

Если вы принимаете только один символ для gender, вы можете обновить как определение таблицы User, так и сохраненный pro c, чтобы принять один символ для gender.

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