如何显示具有多对多关系的SQL Server数据库记录

本文关键字:关系 Server 记录 数据库 SQL 何显示 显示 | 更新日期: 2023-09-27 17:49:13

我正在使用ASP。. NET c#从SQL Server数据库查询输出结果,并尝试让结果在每个球场只显示一条记录,但也在每个球场显示多个联系人详细信息。

相关表为(PK为粗体,FK为斜体):

法院(Court_ID, Court_Name,笔记,城镇,邮政编码)

通讯录(Contact_ID, Contacts_Name, Contacts_no, *Court_ID*, *Court_Contact_Type_ID*)

Contact_Type (Court_Contact_Type_ID, Court_Contact_Type_Desc)

目前我的问题是,每个球场有多少联系人,我就会得到每个球场细节的多次重复。我知道它为什么这样做,但我不知道如何使它按我想要的方式工作。

我不确定解决方案是否存在于SQL查询本身(可能通过嵌套解决…?)或c#代码,因为我使用'HasRows'。我在下面包含了这两个代码片段。

string myQuery = "SELECT Court_Name, Town, Postcode, Note, Contacts_Name, Contacts_no, Court_Contact_Type_Desc " +
                 "FROM Court C, Contacts CON, Contact_type CONT " +
                 "WHERE C.Court_ID = CON.Court_ID AND CON.Court_Contact_Type_ID = CONT.Court_Contact_Type_ID AND C.Court_ID = '3' ";

SqlConnection connection = new SqlConnection(connStr);
SqlCommand myCommand = new SqlCommand(myQuery, connection);
SqlDataReader myDataReader;
connection.Open();
myDataReader = myCommand.ExecuteReader();
if (myDataReader.HasRows)
{
    while (myDataReader.Read())
    {
        string court_name = myDataReader["Court_Name"].ToString();
        string court_town = myDataReader["Town"].ToString();
        string court_pcode = myDataReader["Postcode"].ToString();
        string court_note = myDataReader["Note"].ToString();
        string court_contact_name = myDataReader["Contacts_Name"].ToString();
        string court_contact_desc = myDataReader["Court_Contact_Type_Desc"].ToString();
        string court_contacts_no = myDataReader["Contacts_no"].ToString();
        Response.Write("<strong>" + court_name + "</strong><br>" + court_town + "<br>" + court_pcode + "<p>" + court_note + "</p>" + "<p>" + court_contact_name + " - " + court_contact_desc + " : " + court_contacts_no + "</p>");
    }
}

最终的输出应该看起来像这样:

阿伯加文尼裁判法院
Abergavenny
NP7 5 dl

本庭只供聆讯。附加法庭记录....


联系人姓名1 -代理法院经理:01633 64xxxx
联系人姓名2 -代理办公室经理:01633 64xxxx
联系人姓名3 -代理名单主任:01633 64xxxx
联系人姓名4 -大法官书记:01633 64xxxx

一如既往地感谢您的帮助!

欢呼

如何显示具有多对多关系的SQL Server数据库记录

你可以这样解决这个问题:

  • 将court_id添加到选择列表
  • 添加排序标准,将属于同一法院的行放在彼此旁边
  • 当迭代返回的数据时,查看您之前是否看到过court id
  • 如果这是您第一次看到法院id,请同时显示法院和联系方式
  • 如果你以前见过这个法庭id,只显示联系信息

下面是一个例子:

string myQuery = "SELECT C.Court_ID, Court_Name, Town, Postcode, Note, Contacts_Name, Contacts_no, Court_Contact_Type_Desc " +
             "FROM Court C "+
             "JOIN Contacts CON ON C.Court_ID = CON.Court_ID "+
             "JOIN Contact_type CONT ON CON.Court_Contact_Type_ID = CONT.Court_Contact_Type_ID " +
             "WHERE C.Court_ID = '3' "+ // I assume the search criteria will be different
             "ORDER BY C.Court_ID"; // Very important: records for the same court must be together
...
string last_id = string.Empty;
while (myDataReader.Read())
{
    string court_id = myDataReader["Court_ID"].ToString();
    string court_name = myDataReader["Court_Name"].ToString();
    string court_town = myDataReader["Town"].ToString();
    string court_pcode = myDataReader["Postcode"].ToString();
    string court_note = myDataReader["Note"].ToString();
    string court_contact_name = myDataReader["Contacts_Name"].ToString();
    string court_contact_desc = myDataReader["Court_Contact_Type_Desc"].ToString();
    string court_contacts_no = myDataReader["Contacts_no"].ToString();
    if (last_id != court_id) {
        // Write court AND contact
        Response.Write("<strong>" + court_name + "</strong><br>" + court_town + "<br>" + court_pcode + "<p>" + court_note + "</p>" + "<p>" + court_contact_name + " - " + court_contact_desc + " : " + court_contacts_no + "</p>");
    } else {
        // Write only contact
        Response.Write("<p>" + court_contact_name + " - " + court_contact_desc + " : " + court_contacts_no + "</p>");
    }
    last_id = court_id;
}

你可能想试试这个(如果我得到正确的你想要显示)。假定触点和触点类型为1:1链路。

SELECT Court_Name, Town, Postcode, Note, contacts
    from Court
    where Court_ID = '3'
    CROSS APPLY
    (
    select substring((
        SELECT ',' + Contact_Name+ ' ' +Contacts_no + ' ' + Court_Contact_Type_Desc 
        FROM Contacts join Contact_Type on  Contacts.Court_Contact_Type_ID = Contact_Type.Court_Contact_Type_ID  
        WHERE Contacts.CourtID = Court.CourtID
        FOR XML PATH('')
        ),2,1000)
        as Contacts    
    ) contacts

最直接的方法是将其拆分为2个查询。

第一个查询:获取指定Id的法院。
第二个查询:获取具有指定Id的法院的联系人列表。

好的一面是它使事情简单易懂。而且,如果没有找到联系人(我不知道这种可能性有多大),您仍然可以输出正确的法院地址。

缺点是您对数据库执行了两个SQL查询。这可能是性能方面的考虑。

注意:如果你通过连接字符串来进行SQL查询,就像你的例子一样…小心SQL注入攻击!参见:SQL注入和参数化查询