3

私は、users、permissions、userpermissionsの3つの(関連する)テーブルで構成される非常に単純なデータベースを持っています。基本的な前提は単純です。ユーザーが作成されると、アクセス許可テーブルのすべてのレコードがデフォルト値でuser_permissionsテーブルに自動的に追加されます。これはすべて正常に機能しています。

ただし、現在開発中なので、新しい権限を追加し続けます。もちろん、既存のユーザーは、作成時に権限テーブルに存在していなかったため、これらの新しい権限はありません。そのため、user_permissionsテーブルに現在存在しないすべてのアクセス許可でuser_permissionsテーブルを自動的に更新するために、小さなストアドプロシージャを作成するという素晴らしいアイデアがありました。

つまり、私がやりたいのは(擬似コード)のようなものです。

For each user without x permission in user_permissions, insert into user_permissions user_id and permission_id

SQLPOVからこれを行う方法がよくわかりませんでした。私は結合で遊んだのですが、「存在しません」が、実際にはどこにも到達していません。

ここで私のスキーマを試すことができます:http ://sqlfiddle.com/#!3/b0761 / 3 助けてくれてありがとう!

編集:スキーマ:

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
4

4 に答える 4

2
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)

参照:行がまだ存在しない場合にのみ行を挿入する

于 2012-07-12T18:25:02.107 に答える
1
INSERT dbo.user_permissions([user_id], permission_id, [value])
SELECT u.[user_id], p.permission_id, 1
FROM dbo.user_permissions AS u 
CROSS JOIN dbo.[permissions] AS p
WHERE NOT EXISTS (SELECT 1 FROM dbo.user_permissions 
  WHERE [user_id] = u.[user_id]
  AND permission_id = p.permission_id
)
GROUP BY [user_id], p.permission_id;

余談ですが、たとえばキーワード/予約語user_idなど、区切り文字が必要になる傾向のある名前は避けてください。permissions

于 2012-07-12T18:25:00.157 に答える
1

マンスフィールド、私があなたを正しく理解しているなら、あなたは新しいパーミッションを追加するときにuser_permissionsテーブルに値をシードしたいと思うでしょう。

また、デフォルトで0にすることも想定しています。新しいアクセス許可を挿入した後、このコードを実行すると、現在使用されていないアクセス許可のデフォルト値が0であるすべてのユーザーのuser_permissionsテーブルがシードされます。

--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;
于 2012-07-12T18:47:40.900 に答える
0

以下のクエリは、挿入される不足している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
于 2012-07-12T18:20:16.263 に答える