【问题标题】:Inserting from one table to another issue从一个表插入到另一个问题
【发布时间】:2021-07-27 19:49:38
【问题描述】:

我在尝试使以下存储过程工作时遇到了麻烦。我有一个由 user_id 和 group_id 组成的用户组表。两个 id 都设置为主键而不是 null。我要做的是将当前在组列表中的所有用户插入到该表中。为了更清楚,我正在尝试执行以下操作:

groupIds 50、52、53 中的用户将他们插入组 40。

目前存储过程给了我一个主键约束“PK_user_groups”。无法在对象中插入重复键...重复键值为 (3, 40)。当我查看 user_groups 表时,我确实看到了 3、40 的记录,但组 40 还包含用户 5、8、10。我希望将用户 5、8、10 添加到组 40,但由于用户而失败3 已经有记录了。

这是我的存储过程:

@targetGroupId int,
@groupList nvarchar(max)

DECLARE @list TABLE (groupId int);
    
INSERT INTO @list
SELECT * FROM SplitToInt(@grouplist, ',');

INSERT INTO user_groups(userId, groupId)
SELECT ug.userId, @groupId 
FROM user_groups ug 
INNER JOIN @list l ON ug.groupId = l.groupId
WHERE EXISTS (SELECT userId FROM users_groups WHERE groupId = l.groupId)

【问题讨论】:

  • 所以你想将所有用户从 50、52、53 插入到 40,忽略 40 中的现有用户并忽略重复的用户(比如 50 和 52 中的用户)?
  • 养成懒惰/坏习惯。 INSERT INTO @list SELECT ... 始终指定列列表。始终模式限定对象名称。但是也可能不需要(或没有好处)表变量。建议阅读 Erland 非常有用的网站中的arrays and lists

标签: sql-server tsql stored-procedures sql-insert primary-key


【解决方案1】:

这里有两个问题:

  • 您需要排除组 40 中的所有用户已经
  • 如果用户在多个其他组中,您也不希望添加两次。

我们可以使用EXCEPT 解决第一个问题,这将删除所有现有用户。

EXCEPT 也解决了第二个问题,因为它暗示了DISINCT

INSERT INTO user_groups(userId, groupId)
SELECT ug.userId, @groupId 
    FROM user_groups ug 
    INNER JOIN @list l ON ug.groupId = l.groupId
EXCEPT   -- EXCEPT implies DISTINCT
SELECT userId, groupId
    FROM users_groups;

另外:你应该使用适当的表格类型参数而不是字符串分割:

CREATE TYPE GroupList AS TABLE (groupId int NOT NULL);
CREATE PROC yourProcedureHere
    @targetGroupId int,
    @groupList IntList
AS
.....

【讨论】:

  • 谢谢!这就是我一直在寻找的。​​span>
猜你喜欢
  • 1970-01-01
  • 2014-07-29
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
相关资源
最近更新 更多