【问题标题】:INSERT/DELETE examples in a many-to-many relationship在多对多关系中插入/删除示例
【发布时间】:2015-04-01 06:32:27
【问题描述】:

我有三个表,Users、Roles 和一个联结 UserRoles。

Users       UserRoles         Roles
=======     =============     =========
UserId      UserId            RoleId
Username    RoleId            Role
Firstname   Date

我的表是这样连接的:

Users.UserId -> UserRoles.UserId
Roles.RoleId -> UserRoles.RoleId 

基本上,我正在寻找的是一个简单的例子,它显示:

  1. 如何在 UserRoles 中为具有特定角色的特定用户名插入 UserId 和 RoleId。
  2. 删除特定用户名的角色

我设法对特定用户名的角色进行了简单的选择,如下所示:

SELECT 
    dbo.Roles.Role 
FROM dbo.Roles 
INNER JOIN dbo.UserRoles 
    ON dbo.Roles.RoleId = dbo.UserRoles.RoleId 
INNER JOIN dbo.Users 
    ON dbo.UserRoles.UserId = dbo.Users.UserId 
WHERE (Username = @Username)

【问题讨论】:

  • 我怀疑您的选择查询是否有效?在 Select 查询中检查“WHERE”子句。
  • 是的,它正在工作“@Username”是我的 .NET 代码中的一个参数。也可以这样使用:WHERE (Username = 'John Doe')。谢谢
  • 无法根据当前表设计插入到 UserRoles。因为当我在用户表中插入用户时,用户和角色之间没有关系。我可以将 UserID 插入 UserRoles 但不能插入 RoleID

标签: sql-server many-to-many


【解决方案1】:

要在 UserRoles 中为具有特定角色的特定用户名插入 UserId 和 RoleId,您需要重新设计表,使 User 表具有 Roles 表的外键,如下所示:

Users       UserRoles         Roles
=======     =============     =========
UserId      UserId            RoleId
Username    RoleId            Role
Firstname   Date
RoleId

然后插入如下:

insert into dbo.UserRoles (UserId, RoleId, [Date])
select
    u.UserId,
    r.RoleId,
    getdate() as [Date]
from dbo.Users u
inner join dbo.Roles r
   on r.RoleId = u.RoleId
   and u.Username = @Username

使用上述架构删除特定用户名的角色:

delete r
from dbo.Roles r
inner join dbo.User u
   on r.RoleId = u.Roleid
where u.Username = @Username

编辑:@sidux 建议的另一个解决方案

DELETE ur 
FROM dbo.UserRoles ur 
JOIN dbo.Roles r 
    ON r.RoleId = ur.RoleId 
INNER JOIN dbo.Users u 
    ON ur.UserId = u.UserId 
WHERE (Username = @Username);

【讨论】:

  • SELECT ... INTO 语句创建新表。所以这只适用于初始插入。使用 INSERT INTO ... SELECT
  • @chiridam,感谢您的回复和时间!当我执行删除查询时,我收到此错误:消息 547,级别 16,状态 0,第 1 行 DELETE 语句与 REFERENCE 约束“FK_UsersRoles_Roles”冲突。冲突发生在数据库“UsersRoles”、表“dbo.UserRoles”、列“RoleId”中。声明已终止。
  • @Stefan 该错误表示dbo.UsersRoles 表中有数据引用了您尝试删除的数据。您需要删除并重新创建约束或删除外键引用的数据,方法是从“子”表dbo.UsersRoles 中删除每一行,然后从“父”表dbo.Roles 中删除所有行。跨度>
  • do: DELETE ur FROM dbo.UserRoles ur JOIN dbo.Roles r r.RoleId = ur.RoleId INNER JOIN dbo.Users u ON ur.UserId = u.UserId WHERE (Username = @Username) ;
【解决方案2】:

您可以使用 Merge 并在 proc 中编写所有内容。不要忘记在此处进行测试并提供错误详细信息。

我正在使用@Flg,因为您可能还需要更新语句。在这种情况下,它会有所帮助。

Declare @Flg char(1)='D' -- D/I/U

Declare @Username varchar(50)

Merge into UserRoles  as trg
using(Select
    u.UserId,
    r.RoleId,
    getdate() as [Date]
from dbo.Users u
inner join dbo.Roles r
   on r.RoleId = u.RoleId
   and u.Username = @Username)src
on trg.UserId=src.UserId and trg.RoleId=src.RoleId
when not matched and @Flg='I' THen
insert values(src.UserId,src.RoleId,[Date])
When matched and  @Flg='D' THen
Delete ;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    相关资源
    最近更新 更多