使用JOIN和外键插入SQL Server表

时间:2017-01-25 19:17:52

标签: c# sql sql-server database

我正在尝试创建Students表,Students_Images表和Photo_Collection表。图片路径存储在Student_Images中,每个图片都链接到Photo_Collection行,每个Photo_Collection都与Student行相关。

学生记录已经存在。然后,学生可以为自己创建照片集,并将照片添加到此照片集。因此,每个图像都需要与照片集合相关联,并且每个照片集合都与学生相关联。

我被告知使用以下代码:

create table dbo.Students
(
  ID
    int not null identity( 1, 1 )
    constraint [Students.ID.PrimaryKey]
      primary key clustered,

  Name
    nvarchar( 50 )
)

create table dbo.Student_Images
(
  ID
    int not null identity( 1, 1 )
    constraint [Student_Images.ID.PrimaryKey]
      primary key clustered,

  Student_ID
    int not null
    constraint [Student_Images.to.Student]
      foreign key references dbo.Students( ID )

  Filename
    nvarchar( 250 ) null,

  Description
    nvarchar( 250 ) null
)

create table dbo.Photo_Collection
(
  ID
    int not null identity( 1, 1 )
    constraint [Photo_Collection.ID.PrimaryKey]
      primary key clustered,

  Name
    nvarchar( 250 ) null
)

create table dbo.Photo_Collection_Images
(
  Photo_Collection_ID
    int not null
    constraint [Photo_Collection_Images.to.Photo_Collection]
      foreign key references dbo.Photo_Collection( ID ),

  Student_Image_ID
    int not null
    constraint [Photo_Collection_Images.to.Student_Images]
      foreign key references dbo.Student_Images( ID )
)

以下是填充后这些表格外观的示例:

snip1

我可以使用以下SQL INSERT into Students, Student_ImagesPhoto_Collection

protected void btnAddImage_Click(object sender, EventArgs e)
{

    addImage();
}

public void addStudent()
{
    string cmdText = "INSERT INTO Students (Name) VALUES (@N)";

    //====== Providning information to SQL command object about which query to 
    //====== execute and from where to get database connection information.
    SqlCommand cmd = new SqlCommand(cmdText, con);

    //===== Adding parameters/Values.
    cmd.Parameters.AddWithValue("@N", txtStudentName.Text.ToString());
    //===== To check current state of the connection object. If it is closed open the connection
    //===== to execute the insert query.
    if (con.State == ConnectionState.Closed)
    {
        con.Open();
    }

    //===== Execute Query.
    cmd.ExecuteNonQuery();

    //===== close the connection.
    con.Close();
}

public void addCollection()
{
    string cmdText = "INSERT INTO Photo_Collection (Name) VALUES (@N)";

    //====== Providning information to SQL command object about which query to 
    //====== execute and from where to get database connection information.
    SqlCommand cmd = new SqlCommand(cmdText, con);

    //===== Adding parameters/Values.
    cmd.Parameters.AddWithValue("@N", txtPhotoCollectionName.Text.ToString());
    //===== To check current state of the connection object. If it is closed open the connection
    //===== to execute the insert query.
    if (con.State == ConnectionState.Closed)
    {
        con.Open();
    }

    //===== Execute Query.
    cmd.ExecuteNonQuery();

    //===== close the connection.
    con.Close();
}

public void addImage()
{
    string cmdText = "INSERT INTO Student_Images (Student_Id, Filename, Description) VALUES (@S, @F, @D)";

    //====== Providning information to SQL command object about which query to 
    //====== execute and from where to get database connection information.
    SqlCommand cmd = new SqlCommand(cmdText, con);

    //===== Adding parameters/Values.
    cmd.Parameters.AddWithValue("@S", ddlStudentNames.SelectedValue);
    cmd.Parameters.AddWithValue("@F", fuImage.FileName.ToString());
    cmd.Parameters.AddWithValue("@D", txtImageDescription.Text.ToString());


    //===== To check current state of the connection object. If it is closed open the connection
    //===== to execute the insert query.
    if (con.State == ConnectionState.Closed)
    {
        con.Open();
    }

    //===== Execute Query.
    cmd.ExecuteNonQuery();

    //===== close the connection.
    con.Close();
}
protected void btnAddStudentAndCollection_Click(object sender, EventArgs e)
{
    addStudent();
    addCollection();
}

}

我需要从数据库中检索,如下所示:

snip

但我不知道INSERTSELECT如何使用Photo_Collection_Images表,因为我不知道如何引用外键#我需要将表格链接在一起。

有谁能告诉我如何成功创建照片集并向其添加图像?

我发现这个困难的原因是因为我必须加入一些表格。

2 个答案:

答案 0 :(得分:4)

在不知道ID的情况下将图像插入到集合中。

/* insert without knowing the ids yet */

insert into Photo_Collection_Images (Photo_Collection_Id , Student_Image_Id)
select pc.Id, si.Id
from dbo.photo_collection as pc 
  inner join dbo.student_images as si on pc.student_id = si.student_id
  inner join dbo.students as s on s.id=si.student_id
where s.Name = @S -- student_name
  and pc.Name = @PC -- photo_collection.name
  and si.FileName = @F -- student_images.filename

获取学生的所有馆藏:

/* all collections for one student*/
select pc.Name, si.Id, si.filename, si.description
from dbo.photo_collection as pc
inner join dbo.photo_collection_images pci on pc.id = pci.photo_collection_id
inner join dbo.student_images si on pci.student_image_id = si.id
where si.student_id = @s
-- and pc.name = @N /* one collection */

关于您关于表顺序的问题,这与上一个查询相同:

/* all collections for one student*/
select pc.Name, si.Id, si.filename, si.description
from dbo.student_images as si 
inner join dbo.photo_collection_images pci on pci.student_image_id = si.id
inner join dbo.photo_collection as pc on pc.id = pci.photo_collection_id
where si.student_id = @s
-- and pc.name = @N /* one collection */

按名称获取学生的所有馆藏:

/* all collections for one student*/
select pc.Name, si.Id, si.filename, si.description
from dbo.student as s 
inner join dbo.student_images as si on s.id = si.student_id
inner join dbo.photo_collection_images pci on pci.student_image_id = si.id
inner join dbo.photo_collection as pc on pc.id = pci.photo_collection_id
where s.Name = @s
-- and pc.name = @N /* one collection */

获取所有学生的所有收藏

/* all collections for all students */
select student_name = s.name, pc.Name, si.Id, si.filename, si.description
from dbo.student as s 
inner join dbo.student_images as si on s.id = si.student_id
inner join dbo.photo_collection_images pci on pci.student_image_id = si.id 
inner join dbo.photo_collection as pc on pc.id = pci.photo_collection_id

答案 1 :(得分:2)

不确定我是否理解你,但请考虑以下问题。 它为每个学生提供了他的图像列表以及它们出现的集合。 按学生姓名和照片集名称排序结果时,只要照片集名称或学生名称发生变化,就可以在遍历结果的情况下查看代码,以便在界面中启动新的“组”。

希望它有所帮助。

select s.*, pc.name, si.filename, si.description  from student s
  left outer join student_images si on s.id = si.student_id
  left outer join photo_collection_images pci on pci.student_image_id = si.id
  left outer join photo_collection pc on pci.photo_collection_id = pc.id
order by s.name, pc.name, si.id