Rvn Ответов: 2

Вставка данных в таблицу составных ключей


Я пытаюсь выполнить команду upsert на странице "изменить учетную запись", где пользователи могут редактировать свою информацию. Когда пользователь входит в систему, он будет перенаправлен на страницу "Мой аккаунт", где будет отображаться вся его информация.

На странице редактирования учетной записи будет осуществляться доступ/вставить данные в 3 таблицы: индекс, адрес и Address_Member.

Когда я выполняю команду insert, были вставлены новые данные, но я не знаю, как вставить идентификаторы в таблицу Address_Member, где информация связана друг с другом и в конечном итоге отображается на странице моей учетной записи.

Я также получил эту ошибку: System.Data.SqlClient.SqlException (0x80131904): необходимо объявить скалярную переменную "@AddressID"

Что я уже пробовал:

1. Член

CREATE TABLE [dbo].[Member]
( [MemberID] INT IDENTITY (1, 1) NOT NULL,
[MemberName] VARCHAR (30) NOT NULL,
[Phone] BIGINT NOT NULL,
[Email] VARCHAR (50) NOT NULL,
[Username] VARCHAR (50) NOT NULL,
[Password] NCHAR (30) NOT NULL,
PRIMARY KEY CLUSTERED ([MemberID] ASC) );

2.Адрес
CREATE TABLE [dbo].[Address]
( [AddressID] INT IDENTITY (1, 1) NOT NULL,
[HouseNumber] VARCHAR (10) NOT NULL,
[AddressLine1] VARCHAR (30) NOT NULL,
[AddressLine2] NCHAR (30) NOT NULL,
[City] NCHAR (20) NOT NULL,
[PostCode] NCHAR (7) NOT NULL,
[AddressType] NVARCHAR (MAX) NOT NULL,
PRIMARY KEY CLUSTERED ([AddressID] ASC) );

3.Address_Member
CREATE TABLE [dbo].[Address_Member]
( [MemberID] INT NOT NULL,
[AddressID] INT NOT NULL,
PRIMARY KEY CLUSTERED ([MemberID] ASC, [AddressID] ASC),
CONSTRAINT [FK_Address_Member_Address] FOREIGN KEY ([AddressID]) REFERENCES [dbo].[Address] ([AddressID]), CONSTRAINT [FK_Address_Member_Member] FOREIGN KEY ([MemberID]) REFERENCES [dbo].[Member] ([MemberID]) );

Ниже приведен код в файле editaccount.aspx.cs:
public partial class EditAccount : System.Web.UI.Page
{
    public SqlConnection conn = new SqlConnection("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\Database.mdf;Integrated Security=True");

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            SqlCommand com;
            string str;

            conn.Open();
            str = "SELECT Address.HouseNumber, Address.AddressLine1, Address.AddressLine2, Address.City, Address.PostCode, Address.AddressType, Address_Member.MemberID, Address_Member.AddressID, Member.MemberName, Member.Phone, Member.Email, Member.Username FROM Address INNER JOIN Address_Member ON Address.AddressID = Address_Member.AddressID RIGHT JOIN Member ON Address_Member.MemberID = Member.MemberID WHERE Member.Email = '" + Session["Email"] + "'";
            com = new SqlCommand(str, conn);
            SqlDataReader reader = com.ExecuteReader();

            if (reader.Read())
            {

                TxtEName.Text = reader["MemberName"].ToString();
                LblEUser.Text = reader["Username"].ToString();
                TxtEEmail.Text = reader["Email"].ToString();
                TxtEPhone.Text = reader["Phone"].ToString();
                TxtEType.Text = reader["AddressType"].ToString();
                TxtEHouse.Text = reader["HouseNumber"].ToString();
                TxtEA1.Text = reader["AddressLine1"].ToString();
                TxtEA2.Text = reader["AddressLine2"].ToString();
                TxtECity.Text = reader["City"].ToString();
                TxtEPostcode.Text = reader["PostCode"].ToString();

                reader.Close();
                conn.Close();
            }
        }

    }

    protected void BtnSave_Click(object sender, EventArgs e)
    {
        SqlDataAdapter adapter;

        DataTable dt = new DataTable();
        DataTable dadt = new DataTable();
        DataTable da = new DataTable();



        try
        {
            conn.Open();
            string query = "SELECT Address.HouseNumber, Address.AddressLine1, Address.AddressLine2, Address.City, Address.PostCode, Address.AddressType, Address_Member.MemberID, Address_Member.AddressID, Member.MemberName, Member.Phone, Member.Email, Member.Username FROM Address INNER JOIN Address_Member ON Address.AddressID = Address_Member.AddressID INNER JOIN Member ON Address_Member.MemberID = Member.MemberID WHERE Member.Email = '" + Session["Email"] + "'";
            SqlCommand cmd = new SqlCommand(query, conn);

            adapter = new SqlDataAdapter(cmd);
            adapter.Fill(dt);
            adapter.Fill(dadt);
            adapter.Fill(da);



            if (dt.Rows.Count > 0)
            {
                string membercmd = "UPDATE Member SET MemberName=@MemberName,Email=@Email,Phone=@Phone";
                SqlCommand Member = new SqlCommand(membercmd, conn);

                Member.Parameters.AddWithValue("@MemberName", TxtEName.Text);
                Member.Parameters.AddWithValue("@Email", TxtEEmail.Text);
                Member.Parameters.AddWithValue("@Phone", TxtEPhone.Text);
                Member.ExecuteNonQuery();

            }

            if (da.Rows.Count > 0)
            {
                string Addresscmd = "UPDATE Address SET HouseNumber ='" + TxtEHouse.Text + "', AddressLine1 = '" + TxtEA1.Text + "', AddressLine2 = '" + TxtEA2.Text + "', City = '" + TxtECity.Text + "',PostCode = '" + TxtEPostcode.Text + "', AddressType = '" + TxtEType.Text + "'";
                SqlCommand Address = new SqlCommand(Addresscmd, conn);
                Address.ExecuteNonQuery();

            }
            else
            {

                string AddressInsert = "INSERT INTO Address (HouseNumber, AddressLine1, AddressLine2, City, Postcode, AddressType) VALUES (@HouseNumber, @AddressLine1, @AddressLine2, @City, @Postcode, @AddressType)";
                SqlCommand Address1 = new SqlCommand(AddressInsert, conn);
                Address1.Parameters.AddWithValue("@HouseNumber", TxtEHouse.Text);
                Address1.Parameters.AddWithValue("@AddressLine1", TxtEA1.Text);
                Address1.Parameters.AddWithValue("@AddressLine2", TxtEA2.Text);
                Address1.Parameters.AddWithValue("@City", TxtECity.Text);
                Address1.Parameters.AddWithValue("@Postcode", TxtEPostcode.Text);
                Address1.Parameters.AddWithValue("@AddressType", TxtEType.Text);
                Address1.ExecuteNonQuery();

                string AddressMember = "INSERT INTO Address_Member (AddressID,MemberID) VALUES (@AddressID,@MemberID)";
                SqlCommand Address_Member = new SqlCommand(AddressMember, conn);
                Address_Member.ExecuteNonQuery();
            }


                conn.Close();
                Response.Write("<script>alert('Changes saved')</script>");
                Response.Redirect("~/MyAccount.aspx");


        }



        catch (Exception ex)
        {
            Response.Write("<script>alert('Changes not saved')</script>" + ex);
            conn.Close();
        }

    }
}

2 Ответов

Рейтинг:
1

Wendelius

Некоторые наблюдения
- Как уже отмечалось, используйте параметры, всегда. В некоторых частях вы уже используете их, так что вы знаете, как они работают. Просто используйте их везде.
- Использовать using блоки для правильного размещения объектов, когда они больше не нужны
- Чтобы получить вновь вставленный ключ после вставки в Address таблица, которую вы можете использовать @@IDENTITY (Transact-SQL) | Microsoft Docs[^]


Рейтинг:
0

Patrice T

Не решение вашего вопроса, а еще одна проблема, которая у вас есть.

string Addresscmd = "UPDATE Address SET HouseNumber ='" + TxtEHouse.Text + "', AddressLine1 = '" + TxtEA1.Text + "', AddressLine2 = '" + TxtEA2.Text + "', City = '" + TxtECity.Text + "',PostCode = '" + TxtEPostcode.Text + "', AddressType = '" + TxtEType.Text + "'";

Почему вы используете код, подверженный SQL - инъекции в UPDATE когда INSERT защищен ли он от этого ?

Никогда не создавайте SQL-запрос путем объединения строк. Рано или поздно вы сделаете это с помощью пользовательских вводов, и это откроет дверь к уязвимости под названием "SQL-инъекция", она опасна для вашей базы данных и подвержена ошибкам.
Одна кавычка в имени - и ваша программа выйдет из строя. Если пользователь вводит имя, например "Брайан О'Коннер", может привести к сбою вашего приложения, это уязвимость SQL-инъекции, и сбой-это наименьшая из проблем, вредоносный пользовательский ввод, и он продвигается к командам SQL со всеми учетными данными.
SQL-инъекция - Википедия[^]
SQL-инъекция[^]
Атаки SQL-инъекций на примере[^]
PHP: SQL-инъекция - руководство пользователя[^]
Шпаргалка по предотвращению инъекций SQL - OWASP[^]