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是自找麻烦