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个回答

1
我已尝试上述方法,但在创建视图时感觉像是重复的操作。当更新导入数据库的视图时,我遇到了相同的问题。
您可以通过使用具有创建特权的用户来简单地在本地解决此问题。

1

进入编辑例程部分,在底部更改安全类型从定义者到调用者。


5
去哪里?使用哪个软件? - kenorb
@kenorb,在phpMyAdmin中,您可以更改MySQL存储的例程(过程和函数),例如安全类型。 - Mikl

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

您的SQL语法存在错误,请检查与您的MySQL服务器版本相对应的手册,以获取正确的语法使用方式。在第1行附近出现了“grant all on 'mytable'.* to 'myuser' identified by 'mypass';”这段代码。 - Cerin
@Cerin,只需将“mytable”周围的''更改为``即可。我的回答旨在帮助解决这个问题。请考虑重新考虑你的负评。 - helpse

1

当mysql.proc为空时,但系统始终提示"用户@192.168.% "表名不存在,您只需在mysql命令行中使用root用户并键入:

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

结束!


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来完成,详见这里


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

0

我知道已经晚了,但这对我有用。我的情况是我从生产数据库中导出了一个函数,然后在本地机器上导入它。现在,我为使其正常工作所做的事情如下:

  1. 复制整个函数的 SQL 代码。
  2. 删除本地机器上导入的函数。
  3. 在本地机器上创建一个新函数。
  4. 粘贴您复制的代码。

P.S. 您也可以只从生产环境中复制代码,然后按照步骤3-4进行操作。


0
在我的情况下,删除所有视图解决了这个问题。
DROP VIEW view_name;

-1

这对我没有任何作用。我建议您添加在哪些情况下它适用和不适用。 - David

-2

// 更新所有或特定的程序到您想要的状态,使用现有用户(我的情况是-root)

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

2) FLUSH PRIVILEGES; // 或重新启动服务器


我该如何为我的回复投票?这个解决方案已经帮助我解决了这个问题三次了,虽然我会再检查一遍是否有类似的回复。 - FantomX1

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