3

私はテーブルの「許可」を持っています

| user_id | object_id | readable | writable |

次のルールを使用して、指定されたobject_idが現在のuser_idからアクセスできるかどうかを確認する必要があります。

  • object_idのレコードがまったくない場合は、true を返します
  • 指定されたuser_idのレコードがなくても、object_idのレコードはあるが異なるuser_idのレコードがある場合は、 false を返します。
  • 指定されたuser_idおよびobject_idのレコードがある場合は、指定された読み取りおよび書き込み可能な条件を再度確認します

ネストされたクエリを含まないSQLクエリを構築できるかどうかはわかりませんが、今のところ

select (
    select count(*) 
    from permission 
    where 
        object_id = 123456
    ) == 0 OR (
        select readable=true, writable=false 
        from permission 
        where user_id=1 and object_id=123456
    )

よりエレガントなソリューションはありますか?

ありがとう!

4

3 に答える 3

0
select true as readable, true as writable
where not exists (select 1 permission where object_id = 123456)
union all
select readable, writable
from permission
where user_id = 1 and object_id = 123456

互いに素な可能性があることに注意してください。

  • オブジェクトに対する権限がありません
  • オブジェクトに権限があります
    • ユーザーに権限があります
    • ユーザーに対する権限がありません

つまり、権限が存在しない場合はtrueを返します。それ以外の場合は、ユーザーの権限を返します。このユーザーには存在しないがアクセス許可が存在する場合は、何も返しません(この場合、クエリに明示的に「false、false」を返すようにすることもできますが、なぜ労力を無駄にするのでしょうか?)

(object_id, user_id)また、これは、がテーブルの一意のキーであることを前提としていpermissionます。

于 2012-12-20T13:40:29.233 に答える
0

次のようにできます。

select 
  case 
    when (not exists (select object_id from permissions where object_id=123456)) then true
    when (not exists (select * from permissions where object_id=123456 and id=1)) then false
    else <check your conditions here> 
  end;

araqnid のクエリよりも効率はわずかに劣りますが、読みやすくなる可能性があります。

于 2012-12-20T13:40:01.070 に答える