MySQL错误1449: 指定为定义者的用户不存在。

482

运行以下查询时我会收到一个错误:

SELECT
  `a`.`sl_id`                     AS `sl_id`,
  `a`.`quote_id`                  AS `quote_id`,
  `a`.`sl_date`                   AS `sl_date`,
  `a`.`sl_type`                   AS `sl_type`,
  `a`.`sl_status`                 AS `sl_status`,
  `b`.`client_id`                 AS `client_id`,
  `b`.`business`                  AS `business`,
  `b`.`affaire_type`              AS `affaire_type`,
  `b`.`quotation_date`            AS `quotation_date`,
  `b`.`total_sale_price_with_tax` AS `total_sale_price_with_tax`,
  `b`.`STATUS`                    AS `status`,
  `b`.`customer_name`             AS `customer_name`
FROM `tbl_supplier_list` `a`
  LEFT JOIN `view_quotes` `b`
    ON (`b`.`quote_id` = `a`.`quote_id`)
LIMIT 0, 30

出现的错误信息是:

#1449 - 指定的定义者用户 ('web2vi'@'%') 不存在

我为什么会出现这个错误?如何解决?


8
给我们展示你的SHOW CREATE VIEW 'view_quotes'命令结果。 - jordeu
2
经过一番思考,最简单的做法是将缺失的账户添加到数据库中,这样错误就消失了。不需要复杂的程序。如果您可以添加该账户,请首先尝试这样做。 - user1794918
更简单的方法是直接创建用户! - MinhajulAnwar
1
我在插入时只是遇到了这个问题 - Datadimension
1
为什么定义者需要被定义才能进行任何简单的数据库更改,是谁设计了这种东西。 - kenorb
显示剩余3条评论
41个回答

753

这通常发生在将视图/触发器/存储过程从一个数据库或服务器导出到另一个数据库或服务器时,因为创建该对象的用户不再存在。

您有两个选择:

1. 更改DEFINER

最简单的方法可能是在最初导入数据库对象时,从转储中删除任何DEFINER语句。

稍后更改定义程序会更加棘手:

如何更改视图的定义程序

  1. 运行此SQL以生成必要的ALTER语句

    SELECT CONCAT("ALTER DEFINER=youruser@host VIEW ", table_name, " AS ", view_definition, ";") FROM information_schema.views WHERE table_schema='your-database-name';

  2. 复制并运行ALTER语句

如何更改存储过程的定义程序

例如:

UPDATE `mysql`.`proc` p SET definer = 'user@%' WHERE definer='root@%'

请注意,这将更改所有数据库的定义者。

2. 创建缺失的用户

如果您在使用MySQL数据库时遇到以下错误:

The user specified as a definer ('someuser'@'%') does not exist`

Then you can solve it by using following :

GRANT ALL ON *.* TO 'someuser'@'%' IDENTIFIED BY 'complex-password';
FLUSH PRIVILEGES;

MariaDb版本:

GRANT ALL PRIVILEGES ON *.* TO 'someuser'@'%' IDENTIFIED BY 'complex-password';
FLUSH PRIVILEGES;

来自 http://www.lynnnayko.com/2010/07/mysql-user-specified-as-definer-root.html

这个方法非常有效 - 你只需要将someuser更改为缺失用户的名称。在本地开发服务器上,您可能通常只使用root

还要考虑一下是否实际上需要授予用户ALL权限,或者他们是否可以使用更少的权限。


1
不需要使用 . 和授予权限。 - helpse
5
我认为添加一个没有实际意义的用户会更容易,因为下次进行数据库备份和导入时,你就不需要再次编辑视图和存储过程。 - DarkMukke
1
谢谢,我刚刚删除了有问题的数据表,移除了 DEFINER=\user`@`host`` 然后重新导入。完美解决。 :ok_hand: - giovannipds
1
几乎完成:第一部分需要类似的诗节来描述_triggers_表。 - Otheus
6
如@Otheus所提到的,答案是不完整的。DEFINER 不仅可以是 VIEWS 和 ROUTINES 的一部分,还可以是 EVENTS 和 TRIGGERS 的一部分。要查看缺失 definer 的使用情况,您可以使用以下查询:SELECT DEFINER,'events' FROM INFORMATION_SCHEMA.EVENTS union SELECT DEFINER,'routines' FROM INFORMATION_SCHEMA.ROUTINES union SELECT DEFINER,'triggers' FROM INFORMATION_SCHEMA.TRIGGERS union SELECT DEFINER, 'views' FROM INFORMATION_SCHEMA.VIEWS; - ualinker
显示剩余13条评论

157

创建原始SQL视图或过程的用户已被删除。如果您重新创建该用户,则应解决错误。


4
此外,您需要授予新增用户至少 SELECTEXECUTE 权限。当我将一个数据库备份从一个服务器导出到另一个服务器时,遇到了这个问题,因为创建该程序的用户在测试服务器上不存在。 - drew010
7
谢谢,这非常有帮助。通常,在使用mysqldump进行迁移或部署时,创建VIEW、TRIGGER或PROCEDURE的用户(定义者)在目标系统上可能不同。在这种情况下,只需使用目标系统上有效的用户重新创建过程、触发器或视图(DROP然后重新CREATE)即可解决问题。 - Eric Kigathi
43
您还可以将定义者更改为现有用户:UPDATE mysql.proc SET definer = 'my_new_user@localhost' WHERE db = 'mydatatbase'; - user9903
1
就我个案而言,我有一个指向已删除的DEFINER用户的触发器表。更新触发器用户解决了这个问题。 - Miguel
你还需要授予权限给该用户 :)GRANT ALL ON *.* TO 'someuser'@'%' IDENTIFIED BY 'complex-password'; FLUSH PRIVILEGES; - Victor

60

按照以下步骤操作:

  1. 打开PHPMyAdmin
  2. 选择您的数据库
  3. 选择您的表格
  4. 在顶部菜单中点击“触发器”
  5. 点击“编辑”以编辑触发器
  6. 将定义者从[user@localhost]更改为root@localhost

希望对您有所帮助。


4
这是问题的实际解决方案,而不是创建用户并授予权限,只需更改定义者即可。 - Ankit Chauhan
有没有办法在数据库中找到所有的触发器? - Mrugesh Mistry
3
查找所有触发器:SHOW TRIGGERS。 - JerzySkalski
从命令行中输入“show triggerss”,从PhpMyAdmin选择数据库,然后在导航栏的右上角单击触发器。 - Hussain Rahimi
通过这种方法,如果您有多个触发器,则需要修改和更新所有这些触发器。更好的方法是创建用户并授予权限,然后完成。 - Sami Ullah
这真的很有帮助。最好和简单的解决方案。 - Ishpreet

53

在更新mysql后我遇到了相同的错误。

输入以下命令后,该错误已被修复:

mysql_upgrade -u root
每次升级MySQL时都应该执行mysql_upgrade。它会检查所有数据库中的所有表格,以查看是否与当前版本的MySQL服务器不兼容。如果发现表格可能存在不兼容性,则进行检查。如果发现任何问题,则修复该表格。mysql_upgrade还升级系统表格,以便您可以利用可能已添加的新特权或功能。

不确定为什么这对我没有起作用,我不得不手动删除MySQL Workbench中的所有触发器。 - user752746
当我运行该命令时,控制台显示以下信息:mysql_upgrade客户端现已弃用。升级客户端执行的操作现在由服务器执行。 - daydreamer
从MySQL 5.6升级到MySQL 5.7.33,这个命令完成了工作并解决了问题!感谢这个解决方案。这比篡改数据库信息模式简单得多,也更可靠。遗憾的是,在Ubuntu 20.04上,软件包升级后不会自动执行此命令... - CuriousFab
不建议在MariaDB上运行此程序,我们在运行后遇到了问题。 - ITW

41

像这样创建已删除的用户:

mysql> create user 'web2vi';
或者
mysql> create user 'web2vi'@'%';

3
创建了那个错过的用户之后,遇到另一个错误:ERROR 1142 (42000): TRIGGER command denied to user 'web2vi'@'%' for table 'foo' ,需要在创建用户后添加这个命令 grant all on *.* to 'web2vi'@'%' identified by '' - zhuguowei

39

如果用户存在,则:

mysql> flush privileges;

29

解决方案只需要以下一行查询:

grant all on *.* to 'ROOT'@'%' identified by 'PASSWORD' with grant option;

用你的mysql用户名替换ROOT。 用你的mysql密码替换PASSWORD


3
注意:MySQL用户区分大小写。 - Alessio Cantarella
1
我需要在此之后执行 flush privileges,然后它就可以工作了。谢谢。 - Victor

19

通过运行以下评论进行修复。

grant all on *.* to 'web2vi'@'%' identified by 'root' with grant option;
FLUSH PRIVILEGES;
如果你得到的是some_other而不是web2vi,那么您必须相应地更改名称。

15

对于未来的谷歌搜索者:我在尝试更新一个没有视图的数据库表时收到了类似的消息。经过一些挖掘,发现我已经在该表上导入了触发器,并且这些触发器是由不存在的用户定义的。删除这些触发器解决了问题。


2
触发器是问题所在,我更新了触发器部分的定义者。没有更多问题了。 - Darius
谢谢,这非常有帮助。还需要更新视图。 - toxxxa
确实非常有帮助 :) 我自己永远找不到那个。 - ElChupacabra

13

快速解决方法是绕过并将文件丢弃:

mysqldump --single-transaction -u root -p xyz_live_db > xyz_live_db_bkup110116.sql

2
这个不起作用。定义者包含在转储文件中。 - phil294
如果您使用mysqlpump而非mysqldump,那么您可以使用--skip-definer选项。 - Wouter
@lyhong,我没有详细的解释,但显然--single-transaction在转储期间更改了锁定表的实现方式。或者类似于这样的东西。我不记得在哪里读到的,但这帮助我感到舒适,可以“只是抛出标志”。我也对未经解释的“只需执行此操作”感到不安。无论如何,它对我的情况起作用了。 - SherylHohman
--single-transaction 似乎解决了我的问题。 - kamasuPaul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接