代码之家  ›  专栏  ›  技术社区  ›  Agent_9191

允许用户更新表中的某些记录,但不是全部更新?

  •  0
  • Agent_9191  · 技术社区  · 15 年前

    假设您有一个查找表,它有几个业务逻辑层依赖的默认选项,但您希望允许用户添加/更新/删除该表中的记录。例如,当前状态表将预先填充以下内容,但允许用户更新这些记录的文本以及添加/更新/删除额外记录:

    ID  | StatusName
    -------------
    1   | New
    2   | Inactive
    ... | ...
    

    可以采取哪些方法来实现这种灵活性?我不想“硬编码”预填充的记录,因为用户可能想重新定义它。主要关注的是SQL Server,但理想情况下,这种方法应该是独立于服务器的。

    5 回复  |  直到 9 年前
        1
  •  2
  •   Damir Sudarevic    15 年前
    1. 再添加一列“allowchange”
    2. 在表上添加INSTEADOFUPDATE触发器以截获操作。
    3. 读取allowchange列并相应地更新或放弃记录。

    而不是更新触发器在更新操作之前触发,因此您可以完全控制要执行的操作。

        2
  •  1
  •   Jason Kleban    9 年前

    这种类型的权限逻辑无法使用MS SQL Server实现,更不用说通用RDBMS了。这种类型的逻辑必须在应用程序级别执行。

    你可以用触发器来做一些威慑,但这只能防止意外的变化。

    更新

    SQL 2014/2016现在具有行级安全功能:

    https://azure.microsoft.com/en-us/blog/row-level-security-for-sql-database-is-generally-available/

    https://channel9.msdn.com/Shows/Data-Exposed/Row-Level-Security-Updates

        3
  •  0
  •   Byron Whitlock    15 年前

    向表中添加一个名为“只读”的字段,并在应用程序中对其进行检查。不允许对“只读”字段进行更新/删除。可以轻松添加新字段。短而甜,简单。

        4
  •  0
  •   Jim    15 年前

    有几个选项——您可以在存储过程中总结insert/update/delete,检查您不希望用户覆盖的“特殊”值。对查阅表格所做的所有编辑都必须在存储过程中完成。

    另一种选择是向表中添加一列,称之为“标准”,并将其设置为“是/否”标志。如果为“是”(表示不希望用户更改的标准项),则可以轻松地禁用更新或删除。如果不是(表示它是用户创建的值),则可以允许编辑通过。这使您能够定义数据,而不必对项目ID进行任何特殊的硬编码。

        5
  •  0
  •   Justin Grant    15 年前

    最简单的方法是对该表的所有写入操作执行存储过程——您可以在存储过程的逻辑中实施限制。您可以授予存储过程与基础表不同的权限,这样应用程序的用户就只能通过存储过程进行更改。见 http://www.sommarskog.se/grantperm.html

    您也可以创建一个视图并通过该视图进行写入,尽管我以前从未尝试过这种方法,因此它可能不起作用。

    触发器也可能工作,尽管触发器往往会给应用程序带来额外的复杂性——所以我通常喜欢避免它们。

    这些解决方案的核心要素是没有什么是万无一失的——一个拥有足够特权的坚定用户可以改变他想要的东西。但是,只要你能将你的应用约束到一个特定的用户(或一组用户),并且你可以信任你的高权限用户,不要用特别的查询把事情搞砸,那么你可能就没事了。

    当然,您还需要更改您的模式,这样,无论您选择强制执行限制,您的代码都可以知道要限制哪些行。其他答案中推荐的“附加列”或“附加表”方法是这个附加模式的两个明智选择。“附加表”方法在理论上对我来说是最干净的,但可能会导致次优的查询计划,因为每个查询都需要两个查询之间的联合。这是你在使用前想测试的东西。