Mysql 如何在没有SELECT权限的情况下更新特定记录?

Mysql 如何在没有SELECT权限的情况下更新特定记录?,mysql,Mysql,我想执行如下操作: UPDATE grades SET status="pass" WHERE recno=123; 但是,我希望执行更新的用户帐户对数据库具有只写访问权限,这意味着它没有选择访问权限。这会导致WHERE子句失败 如果有必要,我实际上可以重新写入整个记录,但recno是主键,这将导致写入失败。有办法吗 INSERT INTO grades (recno,name,status,...) VALUES (123, 'chemistry', 'pass',...) ON D

我想执行如下操作:

  UPDATE grades SET status="pass" WHERE recno=123;
但是,我希望执行更新的用户帐户对数据库具有只写访问权限,这意味着它没有选择访问权限。这会导致WHERE子句失败

如果有必要,我实际上可以重新写入整个记录,但recno是主键,这将导致写入失败。有办法吗

INSERT INTO grades (recno,name,status,...) VALUES (123, 'chemistry', 'pass',...)
  ON DUPLICATE KEY UPDATE <everything>;
将值(123,'化学','通过',…)插入等级(记录编号,名称,状态,…)
重复密钥更新;

还是这是错误的方法?此外,它不是“更新特定记录中的特定字段”问题的一般解决方案。

创建一个
视图
,并授予用户对该视图的完全访问权。此视图应仅包含您希望用户能够编辑的行


另一种可能更合适的方法是将这种机制从DBMS中完全抽象出来,而是创建一个允许用户查询的API。

这是一种保护表的特殊方法。在某些情况下,这可能是有意义的,尽管通常您希望提供一些可视窗口,以便用户不会对其对数据的影响视而不见


要完全实现只写数据库,请使用存储过程。这些过程可以完全访问数据库,用户只能被授予对存储过程的访问权限。

这可以通过授予正确的访问级别轻松实现:

REVOKE ALL ON TABLE GRADES FROM USER1; -- to clear out all privileges
GRANT INSERT, UPDATE, DELETE ON TABLE GRADES TO USER1;
这将允许USER1从grades表中插入、更新和删除,而不是选择

USER1
更改为
PUBLIC
或某个组或任何您需要的内容。
根据需要更改权限列表


您的情况是我曾经讲授的IBM数据库课程中的一个经典示例的一个版本: 财务人员可以加薪%,但不知道员工的工资水平是多少,所以

GRANT UPDATE ON TABLE EMPLOYEE TO ACCT_STAFF; -- an no other privileges
这使得他们可以通过执行以下命令来提高15%的工资:

UPDATE EMPLOYEE SET PAY = PAY * 1.15 WHERE EMPLOYEE_ID = 666;

噢!我知道了。我将仅为recno列授予用户选择权限


不过,让问题留待讨论,以防万一有人能给出更好的答案。

更多信息:我有一个可以将日志写入远程服务器的应用程序。应用程序将在程序开始时写入一条新记录,状态为“未完成”。此步骤将从Mysql服务器接收自动生成的recno值。当流程完成时,我想用一个新值修改该记录的状态字段。由于任何人都可以在应用程序上运行字符串并获取其登录凭据,因此我需要授予该帐户对数据库的只写访问权限。您所说的“每个人都可以在数据库上运行字符串”是什么意思?您是否授予每个人写入数据库的权限?这听起来很危险。我的意思是任何人都可以在应用程序上运行字符串。例如,任何人都可以对应用程序进行反向工程,并找出其登录凭据。所以我想把登录限制在它运行所需的操作上。哦,对了,我明白你的意思。是的,任何使用该应用程序的人都可以获得对数据库的写访问权限。理论上,他们可以在上面写下伪造的记录。我看不出有什么办法可以解决这个问题,但现在我可以接受。你知道有人可以只做
updategradessetstatus=NULL
,数据库中的所有记录都会被破坏。因此,您需要创建一个应用程序可以查询的API。这基本上是我已经做过的,但是“WHERE recno=123”子句需要SELECT特权。例如,“错误1143(42000):在表'EMPLOYEE'@EdwardFalk中的'EMPLOYEE_ID'列中,选择拒绝给用户'ACCT_STAFF'的命令。您可以在更新语句中使用
其中recno=123
,而无需对该表进行SELECT访问。我不明白您在说什么。我只是在5.1.41-3ubuntu12.10下使用了您给出和得到的确切命令进行了尝试s错误:“错误1143(42000):为表“EMPLOYEE”中的“EMPLOYEE_ID”列选择拒绝向用户“ACCT_STAFF@'foo.com”发出的命令“。可能服务器的较新版本允许此操作。我当然同意它应该起作用,但它没有起作用。这里的
10.1.37-MariaDB-0+deb9u1
UPDATE
也需要
SELECT
权限。我认为这是最好的答案。现在正在学习如何编写存储过程。虽然攻击者仍然可以通过猜测recno值来破坏数据库,但这种方法效果非常好。我想出了一个安全协议来防止这种情况。谢谢大家的帮助。