424

当我运行以下查询时,出现错误:

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 - The user specified as a definer ('web2vi'@'%') does not exist

为什么我会收到这个错误?我如何解决它?

4

40 回答 40

671

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

你有两个选择:

1.更改定义器

在最初导入数据库对象时,这可能是最容易做到的,方法是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`

然后您可以使用以下方法解决它:

GRANT ALL 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权限,或者他们是否可以使用更少的权限。

于 2013-10-31T12:58:44.290 回答
148

The user who originally created the SQL view or procedure has been deleted. If you recreate that user, it should address your error.

于 2012-05-01T17:08:02.347 回答
53

更新mysql后出现同样的错误。

执行此命令后,错误已得到修复:

mysql_upgrade -u root

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

于 2018-07-23T20:06:55.573 回答
45

按着这些次序:

  1. 转到 PHPMyAdmin
  2. 选择您的数据库
  3. 选择您的餐桌
  4. 在顶部菜单上单击“触发器”
  5. 单击“编辑”以编辑触发器
  6. 将定义者从 [user@localhost] 更改为 root@localhost

希望能帮助到你

于 2016-03-01T05:00:41.820 回答
39

如果用户存在,则:

mysql> flush privileges;
于 2013-01-09T21:24:46.570 回答
36

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

mysql> create user 'web2vi';

或者

mysql> create user 'web2vi'@'%';
于 2014-05-18T12:44:58.770 回答
25

解决方案只是单行查询,如下所示:

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

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

于 2016-09-26T11:27:51.477 回答
16

通过运行以下注释修复。

grant all on *.* to 'web2vi'@'%' identified by 'root' with grant option;
FLUSH PRIVILEGES;

如果你得到some_other而不是web2vi那么你必须相应地更改名称。

于 2016-01-27T19:23:58.317 回答
15

对于未来的谷歌员工:我收到了类似的消息,试图更新数据库中不包含视图的表。经过一番挖掘,事实证明我已经在该表上导入了触发器,这些是不存在的用户定义的东西。删除触发器解决了这个问题。

于 2014-11-27T07:31:52.483 回答
10
grant all on *.* to 'username'@'%' identified by 'password' with grant option;

例子:

grant all on *.* to 'web2vi'@'%' identified by 'password' with grant option;
于 2017-05-22T16:32:44.337 回答
9

快速修复以解决和转储文件:

mysqldump --single-transaction -u root -p xyz_live_db > xyz_live_db_bkup110116.sql
于 2016-01-11T11:17:06.610 回答
8

我与root用户有同样的问题,当我更换它时它对我有用

root@%

经过

root@localhost

因此,如果允许用户 'web2vi' 从 'localhost' 连接,您可以尝试:

web2vi@localhost

我远程连接到数据库。

于 2013-10-09T18:52:45.170 回答
7

您的 mysql 服务器上不存在用户“web2vi”。

请参阅http://dev.mysql.com/doc/refman/5.1/en/error-messages-server.html#error_er_no_such_user

如果该用户确实存在,请检查它可以访问哪些服务器,尽管我认为这将是一个不同的错误(例如,您可能有 web2vi@localhost,但您正在以 web2vi@% 的身份访问数据库(无论如何)

于 2012-04-16T07:27:28.387 回答
7

在将数据库从一台服务器移动到另一台服务器后,这发生在我身上。最初,定义者使用 localhost 和用户。在新服务器上,我们没有该用户,并且主机也已更改。我备份了那个特定的表,并从 phpmyadmin 手动删除了所有触发器。之后它对我来说一直很好。

于 2018-09-14T10:39:20.860 回答
5

为什么我会收到这个错误?我如何解决它?

我花了一个小时才找到解决此类问题的决定。但是,就我而言,我运行了这个:

mysql> UPDATE `users` SET `somefield` = 1 WHERE `user_id` = 2;
ERROR 1449 (HY000): The user specified as a definer ('root'@'%') does not exist

如果您真的想找到问题,只需一一运行此命令即可:

SHOW PROCEDURE STATUS;
SHOW FUNCTION STATUS;
SHOW TRIGGERS;
SHOW FULL TABLES IN database_name WHERE TABLE_TYPE LIKE 'VIEW';

...并且,在他们每个人之后,寻找“定义者”字段。

就我而言,它是有胡子的旧触发器,有些开发人员忘记删除了。

于 2015-12-02T15:27:20.327 回答
4

尝试将您的程序设置为 SECURITY INVOKER

Mysql默认将程序安全设置为“DEFINER”(CREATOR OF)..您必须将安全设置为“调用者”。

于 2015-04-28T13:16:03.180 回答
4

我的 5 美分。

当我尝试从视图中选择时,我遇到了同样的错误。

然而问题似乎是这个视图是从另一个从不同服务器的备份中恢复的视图中选择的。

事实上,是的,用户无效,但从第一眼看去并不明显。

于 2013-08-23T06:20:41.557 回答
4

几分钟前我遇到了同样的问题,我在从 mysql.user 表中删除了一个未使用的用户后遇到了这个问题,但是做一个 alter view 修复了它,这里有一个方便的命令,使它变得非常简单:

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

将其与 mysql 命令行混合(假设 *nix,不熟悉 windows):

> echo above_query | mysql -uuser -p > alterView.sql
> mysql -uuser -ppass databasename < alterView.sql

注意:该命令会在文件上生成额外的 SELECT CONCAT,mysql -uuser -ppass databasename < alterView.sql如果不删除它会失败。

来源:https ://dba.stackexchange.com/questions/4129/modify-definer-on-many-views

于 2012-10-18T16:42:01.250 回答
3

在我的例子中,该表有一个带有不存在的 DEFINER 用户的触发器。

于 2015-02-25T07:41:04.447 回答
3

您的视图“view_quotes”可能已从“web2vi”是有效用户的不同数据库复制到“web2vi”不是有效用户的数据库中。
将“web2vi”用户添加到数据库或更改视图(通常删除 DEFINER='web2vi'@'%' 部分并执行脚本即可)

于 2013-07-31T15:32:48.043 回答
2

你可以试试这个:

$ mysql -u root -p 
> grant all privileges on *.* to `root`@`%` identified by 'password'; 
> flush privileges;
于 2015-04-21T04:05:08.620 回答
2

问题很清楚 - MySQL 找不到指定为定义者的用户。

在从开发服务器同步数据库模型、将其应用到 localhost、对模型进行更改然后将其重新应用到 localhost 后,我​​遇到了这个问题。显然定义了一个视图(我修改过),所以我无法更新我的本地版本。

如何修复(轻松)

注意:它涉及删除,因此它适用于视图,但如果您在表上尝试此操作,请确保您已备份数据。

  1. 以 root 身份登录数据库(或任何有足够能力进行更改的人)。
  2. 删除视图、表格或您遇到的任何问题。
  3. 同步您的新模型 - 它不会抱怨现在不存在的东西。您可能希望从遇到问题的项目定义中删除SQL SECURITY DEFINER部分。

PS 这既不是一个合适的解决方案,也不是最全面的解决方案。我只是把它作为一个可能的(而且非常简单的)解决方案发布。

于 2012-12-25T15:04:53.060 回答
2

来自MySQLCREATE VIEW参考:

DEFINER 和 SQL SECURITY 子句指定在视图调用时检查访问权限时要使用的安全上下文。

此用户必须存在,并且始终最好使用“localhost”作为主机名。所以我认为,如果您检查用户是否存在并在创建视图时将其更改为“localhost”,则不会出现此错误。

于 2012-04-16T07:28:54.360 回答
2

您可以将特定数据库的定义者更改为现有用户:

UPDATE mysql.proc SET definer = 'existing_user@localhost' WHERE db = 'database_name';
于 2021-06-22T11:07:15.097 回答
1

如果这是一个存储过程,您可以执行以下操作:

UPDATE `mysql`.`proc` SET definer = 'YournewDefiner' WHERE definer='OldDefinerShownBefore'

但不建议这样做。

对我来说,更好的解决方案是创建定义器:

create user 'myuser' identified by 'mypass';
grant all on `mytable`.* to 'myuser' identified by 'mypass';
于 2014-06-05T05:04:06.450 回答
1

进入编辑例程部分,在底部,将 Security Type 从 Definer 更改为 Invoker。

于 2012-04-30T19:00:35.473 回答
1

您的一个或多个视图由其他用户创建/注册。您必须检查视图的所有者,并且:

  1. 重新创建用户;正如其他答案所说。或者
  2. 'web2vi'重新创建用户使用ALTER VIEW创建的视图

我曾经遇到过这个问题。

我试图使用 SQLYog 将视图从 BD1 迁移到 BD2。SQLYog 在另一个数据库 (DB2) 中重新创建了视图,但它保留了 BD1 的用户(它们在不同的地方)。后来我意识到我在查询中使用的视图与你有同样的错误,即使我没有创建任何视图。

希望这有帮助。

于 2013-08-07T19:53:14.573 回答
1

就我而言,删除所有视图解决了这个问题。

DROP VIEW view_name;
于 2020-10-28T19:02:34.497 回答
1

这发生在我使用 MYSQL Workbench 6.3 Community 在 Windows 10 上导入转储后,“root@% 不存在”。即使用户存在。首先,我尝试注释掉 DEFINER,但是这不起作用。然后我用“root@localhost”对“root@%”进行了字符串替换,并重新导入了转储。这对我有用。

于 2016-12-05T06:51:21.247 回答
1

我来这里是为了同样的问题,我在我的代码中找不到某个用户正在执行操作的任何地方。显然它来自使用已被长期删除的用户的触发器(数据库是从旧版本恢复的)所以如果你像我一样感到困惑,请查看你的数据库事件/触发器/例程。希望这会对某人有所帮助。

于 2016-01-25T14:17:18.383 回答
1

上面的方法我都试过了,但是在创建视图的时候感觉像是重复动作。我在更新导入数据库的视图时遇到了同样的问题。

您可以通过简单地创建具有创建权限的用户来简单地解决 LOCAL 中的问题。

于 2021-01-27T08:27:09.510 回答
1

对我来说,''从 DEFINER 中删除就可以了。
DEFINER = user@localhost

于 2021-08-29T09:26:23.597 回答
1

就我而言,我在该表上有一个触发器,我无法更新数据,得到相同的错误。

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

解决方案是删除该表上的触发器并重新创建它们,这解决了问题,因为触发器是由另一台服务器的另一个用户创建的,并且在更改托管公司后新服务器上的用户名发生了更改。那是我的 2 美分

于 2015-12-07T15:16:29.217 回答
1

当 mysql.proc 为空时,但系统总是注意到 table_name 不存在“user@192.168.%”,你只需在 mysql 命令行中 root 并键入:

CHECK TABLE `database`.`table_name` QUICK FAST MEDIUM CHANGED;
flush privileges;

超过!

于 2015-09-14T09:38:48.157 回答
1

尝试以下操作:

mysqldump --routines --single-transaction -u root -proot portalv3 > c:\portal.sql
于 2016-02-12T18:45:13.007 回答
0

数据库用户似乎也区分大小写,所以虽然我有一个 root'@'% 用户,但我没有 ROOT'@'% 用户。我通过工作台将用户更改为大写,问题解决了!

于 2015-05-14T12:33:18.130 回答
0

试试这个这是简单的解决方案

mysql -u root -p
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

更多在https://stackoverflow.com/a/42183702/5407056

于 2019-05-18T13:19:15.477 回答
0

另外,要更改触发器的定义器(ALTER 不起作用),您可以这样做:

为每个触发器生成一个 DROP 和一个 CREATE 命令:

SELECT CONCAT("DROP TRIGGER ", trigger_name, ";", " CREATE TRIGGER ", TRIGGER_NAME, " AFTER ", EVENT_MANIPULATION, " ON ", EVENT_OBJECT_SCHEMA, ".", EVENT_OBJECT_TABLE, " FOR EACH ROW ", ACTION_STATEMENT, ";") AS sqlCommand FROM information_schema.triggers WHERE EVENT_OBJECT_SCHEMA = "yourdatabase";

在 foreach 中执行它。当我将生产数据库带到我的开发机器并使用 foreach 遍历所有命令并自动重新创建触发器时,我在我的应用程序中使用它。这让我可以选择自动化它。

PHP/Laravel 中的示例:

    $this->info('DROP and CREATE TRIGGERS');
    $pdo = DB::connection()->getPdo();
    $sql = 'SELECT CONCAT("DROP TRIGGER ", trigger_name, ";", " CREATE TRIGGER ", TRIGGER_NAME, " AFTER ", EVENT_MANIPULATION, " ON ", EVENT_OBJECT_SCHEMA, ".", EVENT_OBJECT_TABLE, " FOR EACH ROW ", ACTION_STATEMENT, ";") AS sqlCommand FROM information_schema.triggers WHERE EVENT_OBJECT_SCHEMA = "mydatabase";';
    $stmt = $pdo->prepare($sql, [PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true]);
    $stmt->execute();
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $stmt->closeCursor();

    foreach($result as $rs){
        $pdo = DB::unprepared($rs['sqlCommand']);
        break;
    }

提示:由于 mysql 缓冲区查询问题,我必须使用 pdo 执行此操作,在此处描述

于 2018-06-20T08:01:04.577 回答
-1

// 将所有或特定程序更新为您想要的,使用现有用户(我的案例 -root)

1) UPDATE mysql.proc p SET definer = 'root@%' WHERE 1=1 LIMIT 1000; (限制子句是因为各种mysql版本在更新时抱怨不受限制或不使用where条件)

2) FLUSH PRIVILEGES; // or restart the server

于 2019-07-08T21:49:23.460 回答
-1

您可以创建具有名称的用户web2vi并授予所有特权

于 2016-09-24T14:37:53.500 回答