2017-01-25 52 views
0

我想創建一個Students表,Students_Images表和Photo_Collection表。圖像路徑存儲在Student_Images中,每個圖像鏈接到Photo_Collection行,並且每個Photo_Collection都與Student行相關。INSERT到SQL Server表使用連接鍵和外鍵

學生記錄已存在。然後,學生可以爲自己創建照片集,並將照片添加到此照片集。因此,每張圖片都需要與一張照片集合相關聯,並且每張照片集合都與一名學生相關聯。

我被告知要使用下面的代碼:

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

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

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表,因爲我不知道怎麼樣引用我需要的外鍵以便將這些錶鏈接在一起。

任何人都可以告訴我如何成功地創建照片集合並添加圖像嗎?

我發現這個困難的原因是因爲我必須加入一些表格。

+0

您不必擔心。數據庫表配置完成後,數據庫將自動查找外鍵。數據庫使用insert語句中的列進行映射。添加/插入時,您必須確保主鍵列不爲空。 – jdweng

+0

@jdweng那麼你是說'INSERT INTO Student'和'INSERT INTO Student_Images'語句後,這兩行的PK將被添加到Photo_Collection_Images表中? – Sweg

+0

@jdweng我上面發佈了我的INSERT語句,它們正確地插入Student,Student_Images和Photo_Collection,但目前沒有任何內容插入到Photo_Collection_Images中 – Sweg

回答

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 
+0

幹得好,很好的答案! –

+0

@StephanLechner謝謝! – SqlZim

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