当我运行以下查询时,我得到一个错误:
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
为什么会出现这个错误?我该怎么解决呢?
几分钟前我遇到了你同样的问题,我从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之后,我遇到了这个问题。显然有一个视图(我修改)定义,所以我不能更新我的本地版本。
如何修复(很容易):
注意:它涉及到删除,所以它对视图工作得很好,但如果你在表上尝试这样做,请确保你有数据备份。
以根用户身份登录数据库(或任何有足够权限进行更改的用户)。
删除视图,表或任何你有问题的东西。
同步你的新模型——它不会抱怨现在不存在的东西。您可能希望从有问题的项定义中删除SQL SECURITY DEFINER部分。
附注:这既不是一个合适的也不是最好的解决方案。我只是把它作为一个可能的(非常简单的)解决方案发布出来。
当创建该对象的用户不再存在时,通常会发生这种情况,即从一个数据库或服务器将视图/触发器/过程导出到另一个数据库或服务器。
你有两个选择:
1. 更改DEFINER
在最初导入数据库对象时,通过从转储中删除任何DEFINER语句,这可能是最容易做到的。
稍后更改定义器就有点棘手了:
如何更改视图定义器
运行此SQL生成必要的ALTER语句
SELECT CONCAT("ALTER DEFINER= ' youruser ' @ ' host ' VIEW ",
table_name, " AS ", view_definition, ";")
从information_schema.views
在table_schema =“your-database-name”;
复制并运行ALTER语句
如何更改存储过程的定义器
例子:
UPDATE `mysql`.`proc` p SET definer = 'user@%' WHERE definer='root@%'
要小心,因为这将更改所有数据库的所有定义器。
2. 创建缺少的用户
如果您在使用MySQL数据库时发现以下错误:
指定为定义器的用户('someuser'@'%')不存在'
然后你就可以解
它使用以下方法:
授予所有*。* 'someuser'@'%' IDENTIFIED BY 'complex-password';
冲洗特权;
从http://www.lynnnayko.com/2010/07/mysql-user-specified-as-definer-root.html
这就像一个魔法——你只需要把someuser改成丢失用户的名字。在本地开发服务器上,通常只使用root。
还要考虑是否真的需要授予用户所有权限,或者他们是否可以用更少的权限。
为什么会出现这个错误?我该怎么解决呢?
我花了一个小时才对这样的问题做出决定。但是,在我的例子中,我运行了这个:
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'。
在我的例子中,它是一个老旧的触发器,某个开发人员忘记删除了。
另外,要更改触发器的定义器(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缓冲区查询问题,在这里描述