我是存储过程的新手。首先,我在MySQL中定义了这样的存储过程。我在起诉MySQL Workbench 6.2
delimiter //
create procedure usp_processUser(
in vu360UserId bigint(20),
in vu360UserNamevarchar(255),
in vu360UserGuid varchar(50),
in email varchar(50),
in firstName varchar(255),
in lastName varchar(255),
in notifyLicenseExpiration bit(1),
in createdDate timestamp,
in updatedDate timestamp
)
begin
if not exists(select * from `AutoAlerts`.`User` where VU360UserID = vu360UserId)
then
insert into `AutoAlerts`.`User` (`VU360UserID`, `VU360UserName`, `UserGuid`, `Email`, `FirstName`, `LastName`, `Notify_License_Expiration`, CreatedDate) VALUES (vu360UserId, vu360UserName, userGuid, email, firstName, lastName, notifyLicenseExpiration, createdDate);
else
UPDATE `AutoAlerts`.`User` SET `VU360UserName`=vu360UserName, `UserGuid`=userGuid, `Email`=email, `FirstName`=firstName, `LastName`=lastName, `Notify_License_Expiration`=notifyLicenseExpiration, UpdatedDate=updatedDate WHERE `VU360UserID`=vu360UserId;
end if;
end//
DELIMITER ;
并像这样调用这个存储过程
call usp_processUser(1231, 'abc@hotmail.com', 'aasdsad', 'abc@gmail.com', 'xxx', 'yyy', 1, '2014-06-25 08:33:40', '2014-12-05 12:00:14');
此过程正在执行,但在工作台中我有时会165 rows effected
,有时会1 rows effected
。
然后我使用on duplicate key
delimiter //
create procedure usp_processUser(
in vu360UserId bigint(20),
in vu360UserName varchar(255),
in vu360UserGuid varchar(50),
in email varchar(50),
in firstName varchar(255),
in lastName varchar(255),
in notifyLicenseExpiration bit(1),
in createdDate timestamp,
in updatedDate timestamp
)
begin
insert into `AutoAlerts`.`User` (`VU360UserID`, `VU360UserName`, `UserGuid`, `Email`, `FirstName`, `LastName`, `Notify_License_Expiration`, CreatedDate)
VALUES (vu360UserId, vu360UserName, userGuid, email, firstName, lastName, notifyLicenseExpiration, createdDate)
on duplicate key update `VU360UserName`=vu360UserName, `UserGuid`=userGuid, `Email`=email, `FirstName`=firstName, `LastName`=lastName, `Notify_License_Expiration`=notifyLicenseExpiration, UpdatedDate=updatedDate;
end//
DELIMITER ;
并像这样调用
call usp_processUser(1231, 'def@hotmail.com', 'asdasd12312', 'abc@gmail.com', 'xxx', 'yyy', 0, NULL, '2014-12-05 12:00:14');
此程序也在执行,但我不断获得2 rows effected
。我想问为什么2 rows
。当我选择像
SELECT * FROM User where VU360UserID = 1231;
然后我只得到一条记录。我想问一下,i.e. getting message sometime 1 row, 2 rows, 165 rows effected
是否与工作台有关,或者我的存储过程中出错了什么?
由于
答案 0 :(得分:0)
正如Local Variable Scope and Resolution所述:
局部变量的名称不应与表列相同。如果SQL语句(例如
SELECT ... INTO
语句)包含对列的引用和声明的具有相同名称的局部变量,则MySQL当前将该引用解释为变量的名称。
此外,正如CREATE PROCEDURE
and CREATE FUNCTION
Syntax所述:
参数名称不区分大小写。
因为您已使用仅与lettercase不同的表名命名参数,然后尝试在WHERE
子句中引用那些没有限定符的表列(在其他任何地方使用列名都是明确的) ,MySQL因此将这些条款评估为重言式:即WHERE VU360UserID=vu360UserId
变为WHERE 1231=1231
- 这总是正确的。
因此,在原始的sproc中,MySQL获取else
语句的if
分支,然后更新所有记录 - 除非该表最初为空,这是仅限then
分支的情况。我认为这与您分别看到165行和1行受影响的情况有关?
在新的sproc中,每个列引用都是明确的 - 这不再是你的问题。根据定义,INSERT ... ON DUPLICATE KEY UPDATE
(带有单个VALUES
子句)只会插入一行或更新单行:因此实际受影响的行数不会超过1.但是,为了表示在调用应用程序中是否插入或更新了一行,MySQL重载了更新的行的含义"响应:
对于
ON DUPLICATE KEY UPDATE
,如果将行作为新行插入,则每行的受影响行值为1;如果现有行已更新,则每行受影响的行值为2.