Sql 在不存在的地方插入foreach x

Sql 在不存在的地方插入foreach x,sql,sql-server,sql-server-2005,stored-procedures,Sql,Sql Server,Sql Server 2005,Stored Procedures,我有一个相当简单的数据库,由三个相关的表组成:用户、权限和用户权限。基本前提很简单:当用户被创建时,权限表中的所有记录都会以默认值自动添加到user_permissions表中。这一切都很好 但是,由于我目前正在开发中,我会继续添加新权限,现有用户当然不会有这些权限,因为这些新权限在创建时不存在于权限表中。因此,我想出了一个绝妙的主意,创建一个小存储过程来自动更新user\u permissions表,其中包含user\u permissions表中当前不存在的所有权限 简言之,我想做的是类似伪

我有一个相当简单的数据库,由三个相关的表组成:用户、权限和用户权限。基本前提很简单:当用户被创建时,权限表中的所有记录都会以默认值自动添加到user_permissions表中。这一切都很好


但是,由于我目前正在开发中,我会继续添加新权限,现有用户当然不会有这些权限,因为这些新权限在创建时不存在于权限表中。因此,我想出了一个绝妙的主意,创建一个小存储过程来自动更新user\u permissions表,其中包含user\u permissions表中当前不存在的所有权限

简言之,我想做的是类似伪代码的事情

For each user without x permission in user_permissions, insert into user_permissions user_id and permission_id
我不太确定如何从SQLPOV执行此操作。我玩了连接,不存在,但没有真正得到任何地方

您可以在此处使用我的模式: 提前感谢您的帮助

编辑:架构:

CREATE TABLE users (
  user_id      int IDENTITY(1, 1) NOT NULL,
  user_name    varchar(255),
  PRIMARY KEY (user_id));

CREATE TABLE permissions (
  permission_id          int IDENTITY(1, 1) NOT NULL, 
  permission_name        varchar(255) NOT NULL, 
  PRIMARY KEY (permission_id));

CREATE TABLE user_permissions (
  user_id       int NOT NULL, 
  permission_id int NOT NULL, 
  value         tinyint DEFAULT 0 NOT NULL,  
  PRIMARY KEY (user_id, 
  permission_id));

ALTER TABLE user_permissions ADD CONSTRAINT FK_user_pe338140 
FOREIGN KEY (permission_id)
REFERENCES permissions (permission_id);

ALTER TABLE user_permissions ADD CONSTRAINT FK_user_pe405324 
FOREIGN KEY (user_id) REFERENCES users (user_id);

INSERT INTO users(user_name) values('test_username');
INSERT INTO users(user_name) values('test_username2');

INSERT INTO permissions(permission_name) VALUES('permission_1')
INSERT INTO permissions(permission_name) VALUES('permission_2')

INSERT INTO user_permissions(user_id, permission_id, value)
VALUES(1, 1, 1)

INSERT INTO user_permissions(user_id, permission_id, value)
VALUES(2, 1, 1)
编辑:查询到目前为止

SELECT a.user_id, b.permission_id, 1 as 'value'
FROM USER_PERMISSIONS a right outer join 
PERMISSIONS b on a.permission_id = b.permission_id

下面的查询将为您提供要插入的缺少的userpermission行:

select a.USER_ID,b.permission_id from users a,permissions b,user_permissions c
   where c.user_id <>a.user_id and c.permission_id <> b.permission_id
另外,您应该避免使用需要分隔符的名称,例如用户id和权限是关键字/保留字

insert into user_permissions (user_id, permission_id)
select
  u.user_id,
  p.permission_id
from
  users u
  cross join permissions p
where
  not exists (select 0 from user_permissions with (updlock, holdlock)
              where user_id = u.user_id and permission_id = p.permission_id)
参考资料:曼斯菲尔德, 如果我理解正确,您希望在添加新权限时为user_permissions表添加一个值

我还假设您希望它默认为0。插入新权限后,运行此代码将为所有用户的user_permissions表设定种子,对于当前未使用的任何权限,默认值为0

--insert into permissions(permission_name) values('newperm');
--select * from permissions
insert into user_permissions(user_id, permission_id, value)
select
  u.user_id, p.permission_id, 0
from
             users u
  cross join permissions p
where
      p.permission_id not in(select permission_id from user_permissions)
;
--select * from user_permissions;

这个问题的可能重复并不能回答我关于如何为每个用户插入这些记录的问题。呃,老式的笛卡尔连接,真的吗?我不喜欢这样做,但这是实现作者期望的方法之一。@Esen这应该说明:我添加了更多的数据尝试-如果我向表中添加数据,你的查询应该返回更少的行,而不是更多的行。如果你让它工作起来,我也很乐意再次向上投票:总是乐于帮助那些努力帮助我的人!如果只为一个用户添加了新权限,该怎么办?根据问题中的示例代码,默认值为1。因此,我有一个绝妙的想法,创建了一个小存储过程来自动更新user\u permissions表,其中包含user\u permissions表中当前不存在的所有权限。所以,他说一个假设是它没有被使用当然可以,但是为什么不编写查询来避免事情没有完全按照预期执行呢?我管理过一个完全像这样的系统,当然,我们有开发人员只为他们的用户测试东西。我过去经常这样做,直到我意识到我可以这样表达:从表a内部连接表C上存在选择*从表B中选择,其中a.AID=B.AID和B.CID=C.CID。我更喜欢它,因为它避免了交叉连接,交叉连接只是作为占位符来获取表名,这样您就可以存在它们,并且它将EXISTS移出WHERE子句,即ANSI样式。
--insert into permissions(permission_name) values('newperm');
--select * from permissions
insert into user_permissions(user_id, permission_id, value)
select
  u.user_id, p.permission_id, 0
from
             users u
  cross join permissions p
where
      p.permission_id not in(select permission_id from user_permissions)
;
--select * from user_permissions;