0

我正在编写一个 MySQL 存储过程,它将选择一行,替换一些列值,然后更新该行。我的问题是 SELECT 语句没有获取所有值。也就是说,在 CLI 中具有值的列在我的存储过程中显示为 NULL。这是我的表定义:

Field           | Type        | Null | Key | Default           | Extra                       |
id              | int(11)     | NO   | PRI | NULL              | auto_increment              |
mac             | varchar(32) | YES  | UNI | NULL              
ip              | varchar(16) | YES  |     | NULL              
type            | varchar(16) | YES  |     | NULL              
location_id     | int(11)     | YES  |     | NULL              
name            | varchar(64) | YES  |     | NULL
manufacturer    | varchar(64) | YES  |     | NULL              
model           | varchar(64) | YES  |     | NULL              
serial_number   | varchar(64) | YES  |     | NULL              
owner           | int(11)     | YES  |     | NULL              
assigned_to     | int(11)     | YES  |     | NULL              
contact         | int(11)     | YES  |     | NULL              
admin           | int(11)     | YES  |     | NULL              
status          | int(11)     | YES  |     | NULL              
authorized      | tinyint(1)  | NO   |     | 0                 
authorized_by   | int(11)     | YES  |     | NULL              
date_authorized | datetime    | YES  |     | NULL              
date_first_seen | datetime    | YES  |     | NULL              
date_last_seen  | datetime    | YES  |     | NULL              
impact          | smallint(6) | YES  |     | NULL              
os_id           | int(11)     | YES  |     | NULL              
updated_at      | timestamp   | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP
org_unit_id     | int(11)     | NO   |     | NULL              
is_virtual      | tinyint(1)  | NO   |     | 0                 
notes           | text        | YES  |     | NULL

这是我的代码的一部分:

CREATE PROCEDURE `updatehw`(mac varchar(32), ipaddr varchar(16), typ varchar(16),
                            loc int, name varchar(64), maker varchar(64),
                            model varchar(64), ser_no varchar(64), owner int,
                            assignee int, contact int, admin int, status int,
                            authorized tinyint, authorizer int, auth_date datetime,
                            impact smallint, os_id int, org int, virtual tinyint,
                            seen tinyint, notes text, 
                OUT error int, OUT error_text varchar(64))
   MODIFIES SQL DATA
proc_label: BEGIN
   Declare rc INT;
   Declare hw_mac varchar(32);
   Declare hw_ip varchar(16);
   Declare hw_type varchar(16);
   Declare hw_location_id INT;
   Declare hw_name varchar(64);
   Declare hw_manufacturer varchar(64);
   Declare hw_model varchar(64);
   Declare hw_serial_number varchar(64);
   Declare hw_owner INT;
   Declare hw_assigned_to INT;
   Declare hw_contact INT;
   Declare hw_admin INT;
   Declare hw_status INT;
   Declare hw_authorized tinyint;
   Declare hw_authorized_by INT;
   Declare hw_date_authorized, l_date_authorized DATETIME;
   Declare hw_date_first_seen DATETIME;
   Declare hw_date_last_seen DATETIME;
   Declare hw_impact smallint;
   Declare hw_os_id INT;
   Declare hw_updated_at timestamp;
   Declare hw_org_unit_id INT;
   Declare hw_is_virtual tinyint;
   Declare hw_notes text;

   Declare Exit Handler for SQLEXCEPTION
   BEGIN
      ROLLBACK;
      Set error = -99;
      Set error_text = 'SQL Exception detected';
   End;

   Set error = 0;
   Set error_text = NULL;
   insert into log (msg) values ("updateHW starting"); -- DEBUG

   Start Transaction;
   -- See if the row exists and lock it
   insert into log (msg) values (concat_ws('=','ipaddr',ipaddr)); -- DEBUG
   Select mac, ip, type, location_id, name, manufacturer,
          model, serial_number, owner, assigned_to, contact,
          admin, status, authorized, authorized_by,
          date_authorized, date_first_seen, date_last_seen,
          impact, os_id, org_unit_id, is_virtual, notes
     into hw_mac, hw_ip, hw_type, hw_location_id, hw_name, hw_manufacturer,
          hw_model, hw_serial_number, hw_owner, hw_assigned_to, hw_contact,
          hw_admin, hw_status, hw_authorized, hw_authorized_by,
          hw_date_authorized, hw_date_first_seen, hw_date_last_seen,
          hw_impact, hw_os_id, hw_org_unit_id, hw_is_virtual, hw_notes
     from hardware where ip=ipaddr
     lock in share mode;
   insert into log (msg) values (concat_ws(' ',"hw_owner after select is",hw_owner)); -- DEBUG
   insert into log (msg) values (concat_ws(' ',"hw_authorized_by after select is",hw_authorized_by)); -- DEBUG
   insert into log (msg) values (concat_ws(' ',"hw_authorized after select is",hex(hw_authorized))); -- DEBUG
   insert into log (msg) values (concat_ws(' ',"hw_is_virtual after select is",hex(hw_is_virtual))); -- DEBUG
   Select found_rows() into rc;
   If rc = 0 THEN
      set error = -11;
      set error_text = 'Entry not found';
      ROLLBACK;
      Leave proc_label;
   End if;
.
.
.

CLI 说这是我的行的内容(我正在使用占位符值):

             id: 22
            mac: mac
             ip: ip
           type: type2
    location_id: 1
           name: name
   manufacturer: maker
          model: model
  serial_number: serial
          owner: 1
    assigned_to: 1
        contact: 1
          admin: 1
         status: 1
     authorized: 0
  authorized_by: 1
date_authorized: 2013-03-20 08:46:16
date_first_seen: 2013-03-20 09:04:39
 date_last_seen: NULL
         impact: 0
          os_id: NULL
     updated_at: 2013-03-25 09:56:04
    org_unit_id: 1
     is_virtual: 1
          notes: Another note

我的日志显示列 hw_authorized 和 hw_owner 被读取为 NULL 而不是实际值。

| 2013-03-25 13:12:23 |    NULL | updateHW starting                  |
| 2013-03-25 13:12:23 |    NULL | ipaddr=ip                          |
| 2013-03-25 13:12:23 |    NULL | hw_owner after select is           |
| 2013-03-25 13:12:23 |    NULL | hw_authorized_by after select is 1 |
| 2013-03-25 13:12:23 |    NULL | hw_authorized after select is      |
| 2013-03-25 13:12:23 |    NULL | hw_is_virtual after select is 1    |

这是我的表的创建方式:

CREATE TABLE hardware (
id int(11) NOT NULL AUTO_INCREMENT,
mac varchar(32) DEFAULT NULL,
ip varchar(16) DEFAULT NULL,
type varchar(16) DEFAULT NULL,
location_id int(11) DEFAULT NULL,
name varchar(64) DEFAULT NULL,
manufacturer varchar(64) DEFAULT NULL,
model varchar(64) DEFAULT NULL,
serial_number varchar(64) DEFAULT NULL,
owner int(11) DEFAULT NULL,
assigned_to int(11) DEFAULT NULL,
contact int(11) DEFAULT NULL,
admin int(11) DEFAULT NULL,
status int(11) DEFAULT NULL,
authorized tinyint(1) NOT NULL DEFAULT 0,
authorized_by int(11) DEFAULT NULL,
date_authorized datetime DEFAULT NULL,
date_first_seen datetime DEFAULT NULL,
date_last_seen datetime DEFAULT NULL,
impact smallint(6) DEFAULT NULL,
os_id int(11) DEFAULT NULL,
updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
org_unit_id int(11) NOT NULL,
is_virtual tinyint(1) NOT NULL DEFAULT 0,
notes text,
PRIMARY KEY (id),
UNIQUE KEY hardware_idx (mac)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=latin1

和一个示例插入:

Insert into hardware (mac, ip, type, location_id, name, manufacturer,
                  model, serial_number, owner, assigned_to, contact,
                  admin, status, authorized, authorized_by,
                  date_authorized, date_first_seen,
                  date_last_seen, impact, os_id, org_unit_id, 
                  is_virtual, notes)
          values ('mac','ip','type',1,'name','maker','model','serial',
                  1,1,1,1, 1, 0,
                  1, current_timestamp(), current_timestamp(), current_timestamp(),
                  0, NULL, 1, 1, "Test");

我究竟做错了什么?

我在 CentOS 6.4 上使用 MySql 5.1。

4

1 回答 1

0

Problem resolved. Apparently, there are secret reserved words one cannot use in stored procedures. I renamed the 'authorized' column to 'is_authorized' and the SELECT statement returned the expected value.

FTR, the column names I had to change were: name, model, status, impact, and os_id.

BTW, I tried using ticks around these column names, but it didn't help.

于 2013-04-03T13:28:14.337 回答