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

当我运行以下查询时,我得到一个错误:

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

为什么会出现这个错误?我该怎么解决呢?

691290 次浏览

用户web2vi在你的mysql服务器上不存在。

看到http://dev.mysql.com/doc/refman/5.1/en/error-messages-server.html#error_er_no_such_user

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

CREATE VIEWMySQL参考:

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

该用户必须存在,最好使用“localhost”作为主机名。我认为如果你检查用户是否存在并在创建视图上将其更改为localhost你就不会有这个错误。

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

最初创建SQL视图或过程的用户已被删除。如果您重新创建该用户,它应该可以解决您的错误。

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

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

问题很明显——MySQL无法找到指定为定义器的用户。

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

如何修复 (容易)

注意:它涉及到删除,所以它对视图工作得很好,但如果你在表上尝试这样做,请确保你有数据备份。

  1. 以根用户身份登录数据库(或任何有足够权限进行更改的用户)。
  2. 删除视图,表或任何你有问题的东西。
  3. 同步你的新模型——它不会抱怨现在不存在的东西。你可能想要从你有问题的项目定义中删除SQL安全定义器部分。

附注:这既不是一个合适的也不是最好的解决方案。我只是把它作为一个可能的(非常简单的)解决方案发布出来。

如果用户存在,则:

mysql> flush privileges;

你的视图,"view_quotes"可能已经从一个不同的数据库,其中"web2vi"是一个有效的用户复制到一个数据库,其中"web2vi"不是一个有效的用户 将"web2vi"用户添加到数据库或更改视图(通常删除DEFINER='web2vi'@'%'部分并执行脚本将完成此操作)

一个或几个视图是由另一个用户创建/注册的。你必须检查视图的所有者,并:

    重新创建用户;正如其他答案所说。 李或< / >
  1. 重新创建由用户'web2vi'使用改变观点创建的视图

我曾经遇到过这个问题。

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

希望这对你有所帮助。

我的5美分。

当我试图从视图中选择时,我也犯了同样的错误。

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

事实上,是的,用户是无效的,但从第一眼看不清楚在哪里。

我有同样的问题与根用户和它为我工作时,我替换

root@%

通过

root@localhost

所以,如果用户'web2vi'被允许从'localhost'连接,你可以尝试:

web2vi@localhost

我远程连接到数据库了。

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

你有两个选择:

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. Copy and run the ALTER statements

How to change the definer for stored procedures

Example:

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;

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

这就像一个魅力-你只需要将someuser更改为缺少的用户的名称。在本地开发服务器上,通常只使用root

还要考虑是否实际需要授予用户ALL权限,或者他们是否可以做得更少。

创建被删除的用户,如下所示:

mysql> create user 'web2vi';

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

如果这是一个存储过程,你可以这样做:

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

但这是不建议的。

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

create user 'myuser' identified by 'mypass';
grant all on `mytable`.* to 'myuser' identified by 'mypass';

对于未来的谷歌人:我收到了类似的消息,试图更新数据库中不包含视图的表。经过一番挖掘,我发现我在那个表上导入了触发器,而那些是由不存在的用户定义的东西。放下触发器就解决了问题。

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

你可以试试这个:

$ mysql -u root -p
> grant all privileges on *.* to `root`@`%` identified by 'password';
> flush privileges;

试着将你的程序设置为 SECURITY INVOKER < / p >

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

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

当mysql。Proc是空的,但是系统总是提示“user@192.168.%”的table_name不存在,你只需要在mysql命令行中输入root:

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

结束了!

为什么会出现这个错误?我该怎么解决呢?

我花了一个小时才对这样的问题做出决定。但是,在我的例子中,我运行了这个:

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';

...然后,在每个字段之后,查找字段'definer'。

在我的例子中,它是一个老旧的触发器,某个开发人员忘记删除了。

在我的例子中,我在那个表上有一个触发器,我不能更新数据得到相同的错误。

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

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

快速修复工作周围和转储文件:

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

我来这里是为了同样的问题,我在我的代码中找不到某个用户正在做动作的任何地方。 显然,这是从一个触发器,正在使用一个用户被删除了很长时间(db是从一个旧版本恢复) 所以,如果你像我一样感到困惑,看看你的db事件/触发器/例程。 希望这能帮助到一些人。< / p >

通过运行以下注释修复。

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

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

试试下面的方法:

mysqldump --routines --single-transaction -u root -proot portalv3 > c:\portal.sql

遵循以下步骤:

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

希望能有所帮助

你可以创建一个名为web2vi的用户,并授予所有权限

解决方案只是一个单行查询如下:

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

ROOT替换为mysql用户名。

.使用mysql密码替换PASSWORD
这发生在我用MYSQL Workbench 6.3 Community在Windows 10上导入转储文件后,提示“root@%不存在”。即使用户存在。 首先,我试图注释掉DEFINER,但是,这没有工作。 然后,我用“root@localhost”替换了“root@ %”上的字符串,并重新导入转储。

grant all on *.* to 'username'@'%' identified by 'password' with grant option;

例子:

grant all on *.* to 'web2vi'@'%' identified by 'password' with grant option;

另外,要更改触发器的定义器(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;
}

提示:我必须用pdo来做,因为mysql缓冲区查询问题,描述在这里

我在更新mysql后得到了同样的错误。

这个错误已经被修复:

mysql_upgrade -u root

mysql_upgrade应该在每次升级MySQL时执行。它 方法检查所有数据库中的所有表是否与 MySQL服务器的当前版本。如果一个表被发现有 可能的不兼容性,它被检查。如果发现任何问题, 桌子修好了。Mysql_upgrade也升级系统表 这样你就可以利用新的特权或能力

当我将数据库从一台服务器移动到另一台服务器时,就发生了这种情况。最初,定义者使用本地主机和用户。在新的服务器上,我们没有这个用户,主机也被改变了。我对那个特定的表和从phpmyadmin手动删除所有触发器进行了备份。在那之后,我一直工作得很好。

< p >试试这个 这是一个简单的解

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

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

//更新所有或特定的程序到你想要的,使用现有的用户(我的case -root)

< p > 1) UPDATE mysql.proc p SET definer = 'root@%' WHERE 1=1 LIMIT 1000; (limit子句是由于不同的mysql版本在更新时没有使用limit或没有使用条件而导致的)

< p > 2) FLUSH PRIVILEGES; // or restart the server < / p >

在我的例子中,删除所有视图解决了这个问题。

DROP VIEW view_name;

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

您可以在LOCAL中简单地通过创建具有create权限的User来解决这个问题。

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

UPDATE mysql.proc SET definer = 'existing_user@localhost' WHERE db = 'database_name';
对我来说,从DEFINER中删除''就成功了。
DEFINER = user@localhost < / p >