MySQL 存储过程错误 1146
MySQL Error 1146 On Stored Procedure
我正在尝试使用以下存储过程将值设置为 table。
Create Definer = Current_User Procedure sp_set_drivers_cost (In driver_id Int)
Not Deterministic
Begin
-- Variable that will holds the driver's total cost.
Declare driver_cost Numeric(65,2) Default 0;
-- Declaring loop_counter and a varialbe that will hold the sum of the cost.
Declare loop_counter, temp_table_sum Int Default 1;
-- Variable that will hold the driver's total cost.
Declare local_cost Numeric(65,2) Default 0;
Declare temp1 int;
-- Dropping table if exists.
Drop Table If Exists MyDB.temp_policy_id;
-- Creating temp table that will hold the policy ids that the given driver is covered for.
Create Table MyDB.temp_policy_id (
id int not null auto_increment,
policy_id int not null default 0,
Primary Key (id)
);
-- Inserting the policy ids for the given driver id;
Insert Into MyDB.temp_policy_id(policy_id)
Select fk_policy_id
From link_drivers_policies
Where fk_driver_id = driver_id;
-- Counting the rows of the temp table.
Set temp_table_sum = (Select Count(*) From temp_policy_id);
-- Looping through the rows of the table in order to get the total cost for each driver.
While loop_counter <= temp_table_sum Do
Set temp1 = (Select policy_id From temp_policy_id Where id = loop_counter);
-- Getting the total cost, for the given driver, based on the policies they are covered by.
Set local_cost = local_cost + (Select cost From policies Where id = temp1);
-- Incrementing the loop counter by 1.
Set loop_counter = loop_counter + 1;
End While;
-- Updating the drivers cost.
Update MyDB.drivers
Set cost = local_cost
Where id = driver_id;
Drop Table MyDB.temp_policy_id;
End//
当我尝试测试过程时,通过像 "call sp_set_drivers_cost" 那样调用它,我得到以下错误:
调用 sp_set_drivers_cost(1) 错误代码:1146。Table 'MyDB.MyDB' 不存在 0.437 秒。
我试过 childinsh 解决方案,比如修改 return 数值的变量,省略数据库名称,并重新启动 MySQL 服务(我在 Windows 7).此外,我在过程中创建的临时 table 存在于数据库中。所以我的猜测是错误发生在循环内,或者在 "Update" 语句期间。我正在使用 InnoDB。谢谢。
更新
在尝试更新 table "drivers" 时,我也遇到了同样的错误。
正如@Norbert van Nobelen 所指出的那样,我尝试实施 发布的解决方案,但无济于事。此外,我想声明,我在编写其余存储过程的部分使用了制表符来缩进我的代码,并且没有出现任何错误。
由于不清楚问题出在哪里,所以你遇到了"Why is there no debugger for stored procedures"的情况。
要调试编译良好但不编译的存储过程运行,您可以采用两种方法:
- 向过程添加日志记录行
- 拆开来运行一步一步来
选项 1:添加日志行
因为日志行只是一个 SELECT
语句。当您调用过程时,这会记录在命令行中。例如:
Create Definer = Current_User Procedure sp_set_drivers_cost (In driver_id Int)
Not Deterministic
Begin
-- Variable that will holds the driver's total cost.
Declare driver_cost Numeric(65,2) Default 0;
-- Declaring loop_counter and a varialbe that will hold the sum of the cost.
Declare loop_counter, temp_table_sum Int Default 1;
-- Variable that will hold the driver's total cost.
Declare local_cost Numeric(65,2) Default 0;
Declare temp1 int;
-- Dropping table if exists.
Drop Table If Exists MyDB.temp_policy_id;
-- Creating temp table that will hold the policy ids that the given driver is covered for.
Create Table MyDB.temp_policy_id (
id int not null auto_increment,
policy_id int not null default 0,
Primary Key (id)
);
SELECT "Step 1 finished";
...
这样您就可以了解执行的内容和未执行的内容。
选项 2:逐步分解您的程序
这与日志行类似,只是您需要为每个步骤重新创建过程:
Create Definer = Current_User Procedure sp_set_drivers_cost (In driver_id Int)
Not Deterministic
Begin
-- Variable that will holds the driver's total cost.
Declare driver_cost Numeric(65,2) Default 0;
-- Declaring loop_counter and a varialbe that will hold the sum of the cost.
Declare loop_counter, temp_table_sum Int Default 1;
-- Variable that will hold the driver's total cost.
Declare local_cost Numeric(65,2) Default 0;
Declare temp1 int;
-- Dropping table if exists.
Drop Table If Exists MyDB.temp_policy_id;
-- Creating temp table that will hold the policy ids that the given driver is covered for.
Create Table MyDB.temp_policy_id (
id int not null auto_increment,
policy_id int not null default 0,
Primary Key (id)
);
END;
CALL temp_policy_id;
然后是下一部分:
Create Definer = Current_User Procedure sp_set_drivers_cost (In driver_id Int)
Not Deterministic
Begin
-- Variable that will holds the driver's total cost.
Declare driver_cost Numeric(65,2) Default 0;
-- Declaring loop_counter and a varialbe that will hold the sum of the cost.
Declare loop_counter, temp_table_sum Int Default 1;
-- Variable that will hold the driver's total cost.
Declare local_cost Numeric(65,2) Default 0;
Declare temp1 int;
-- Dropping table if exists.
Drop Table If Exists MyDB.temp_policy_id;
-- Creating temp table that will hold the policy ids that the given driver is covered for.
Create Table MyDB.temp_policy_id (
id int not null auto_increment,
policy_id int not null default 0,
Primary Key (id)
);
-- Inserting the policy ids for the given driver id;
Insert Into MyDB.temp_policy_id(policy_id)
Select fk_policy_id
From link_drivers_policies
Where fk_driver_id = driver_id;
END;
CALL temp_policy_id;
等等,直到你的错误出现。大多数时候,当知道问题的确切路线时,解决方案就会变得更加清晰。
在 Windows 上,MySQL 必须忽略大小写,因为它使用文件和目录作为表和数据库。 Windows 忽略大小写。也就是说 CREATE TABLE lcase...
和 CREATE TABLE LCASE...
不能在 Windows 上共存。
改lower_case_table_names
是自找麻烦
我正在尝试使用以下存储过程将值设置为 table。
Create Definer = Current_User Procedure sp_set_drivers_cost (In driver_id Int)
Not Deterministic
Begin
-- Variable that will holds the driver's total cost.
Declare driver_cost Numeric(65,2) Default 0;
-- Declaring loop_counter and a varialbe that will hold the sum of the cost.
Declare loop_counter, temp_table_sum Int Default 1;
-- Variable that will hold the driver's total cost.
Declare local_cost Numeric(65,2) Default 0;
Declare temp1 int;
-- Dropping table if exists.
Drop Table If Exists MyDB.temp_policy_id;
-- Creating temp table that will hold the policy ids that the given driver is covered for.
Create Table MyDB.temp_policy_id (
id int not null auto_increment,
policy_id int not null default 0,
Primary Key (id)
);
-- Inserting the policy ids for the given driver id;
Insert Into MyDB.temp_policy_id(policy_id)
Select fk_policy_id
From link_drivers_policies
Where fk_driver_id = driver_id;
-- Counting the rows of the temp table.
Set temp_table_sum = (Select Count(*) From temp_policy_id);
-- Looping through the rows of the table in order to get the total cost for each driver.
While loop_counter <= temp_table_sum Do
Set temp1 = (Select policy_id From temp_policy_id Where id = loop_counter);
-- Getting the total cost, for the given driver, based on the policies they are covered by.
Set local_cost = local_cost + (Select cost From policies Where id = temp1);
-- Incrementing the loop counter by 1.
Set loop_counter = loop_counter + 1;
End While;
-- Updating the drivers cost.
Update MyDB.drivers
Set cost = local_cost
Where id = driver_id;
Drop Table MyDB.temp_policy_id;
End//
当我尝试测试过程时,通过像 "call sp_set_drivers_cost" 那样调用它,我得到以下错误: 调用 sp_set_drivers_cost(1) 错误代码:1146。Table 'MyDB.MyDB' 不存在 0.437 秒。
我试过 childinsh 解决方案,比如修改 return 数值的变量,省略数据库名称,并重新启动 MySQL 服务(我在 Windows 7).此外,我在过程中创建的临时 table 存在于数据库中。所以我的猜测是错误发生在循环内,或者在 "Update" 语句期间。我正在使用 InnoDB。谢谢。
更新 在尝试更新 table "drivers" 时,我也遇到了同样的错误。
正如@Norbert van Nobelen 所指出的那样,我尝试实施
由于不清楚问题出在哪里,所以你遇到了"Why is there no debugger for stored procedures"的情况。
要调试编译良好但不编译的存储过程运行,您可以采用两种方法:
- 向过程添加日志记录行
- 拆开来运行一步一步来
选项 1:添加日志行
因为日志行只是一个 SELECT
语句。当您调用过程时,这会记录在命令行中。例如:
Create Definer = Current_User Procedure sp_set_drivers_cost (In driver_id Int)
Not Deterministic
Begin
-- Variable that will holds the driver's total cost.
Declare driver_cost Numeric(65,2) Default 0;
-- Declaring loop_counter and a varialbe that will hold the sum of the cost.
Declare loop_counter, temp_table_sum Int Default 1;
-- Variable that will hold the driver's total cost.
Declare local_cost Numeric(65,2) Default 0;
Declare temp1 int;
-- Dropping table if exists.
Drop Table If Exists MyDB.temp_policy_id;
-- Creating temp table that will hold the policy ids that the given driver is covered for.
Create Table MyDB.temp_policy_id (
id int not null auto_increment,
policy_id int not null default 0,
Primary Key (id)
);
SELECT "Step 1 finished";
...
这样您就可以了解执行的内容和未执行的内容。
选项 2:逐步分解您的程序
这与日志行类似,只是您需要为每个步骤重新创建过程:
Create Definer = Current_User Procedure sp_set_drivers_cost (In driver_id Int)
Not Deterministic
Begin
-- Variable that will holds the driver's total cost.
Declare driver_cost Numeric(65,2) Default 0;
-- Declaring loop_counter and a varialbe that will hold the sum of the cost.
Declare loop_counter, temp_table_sum Int Default 1;
-- Variable that will hold the driver's total cost.
Declare local_cost Numeric(65,2) Default 0;
Declare temp1 int;
-- Dropping table if exists.
Drop Table If Exists MyDB.temp_policy_id;
-- Creating temp table that will hold the policy ids that the given driver is covered for.
Create Table MyDB.temp_policy_id (
id int not null auto_increment,
policy_id int not null default 0,
Primary Key (id)
);
END;
CALL temp_policy_id;
然后是下一部分:
Create Definer = Current_User Procedure sp_set_drivers_cost (In driver_id Int)
Not Deterministic
Begin
-- Variable that will holds the driver's total cost.
Declare driver_cost Numeric(65,2) Default 0;
-- Declaring loop_counter and a varialbe that will hold the sum of the cost.
Declare loop_counter, temp_table_sum Int Default 1;
-- Variable that will hold the driver's total cost.
Declare local_cost Numeric(65,2) Default 0;
Declare temp1 int;
-- Dropping table if exists.
Drop Table If Exists MyDB.temp_policy_id;
-- Creating temp table that will hold the policy ids that the given driver is covered for.
Create Table MyDB.temp_policy_id (
id int not null auto_increment,
policy_id int not null default 0,
Primary Key (id)
);
-- Inserting the policy ids for the given driver id;
Insert Into MyDB.temp_policy_id(policy_id)
Select fk_policy_id
From link_drivers_policies
Where fk_driver_id = driver_id;
END;
CALL temp_policy_id;
等等,直到你的错误出现。大多数时候,当知道问题的确切路线时,解决方案就会变得更加清晰。
在 Windows 上,MySQL 必须忽略大小写,因为它使用文件和目录作为表和数据库。 Windows 忽略大小写。也就是说 CREATE TABLE lcase...
和 CREATE TABLE LCASE...
不能在 Windows 上共存。
改lower_case_table_names
是自找麻烦