更清楚:
表 thetable (id int, username varchar(30), password varchar(30), last_successful_login timestamp, last_unsuccessful_login timestamp, another_variable varchar(30))
包含以下行:(1,“tgh”,“pass”,0,0,“another”)
1)用户/密码对错误,但用户名
我希望select id from thetable where username="tgh" and password="wrongpass" and another_variable="another";
使用last_unsuccessful_login
和username="tgh"
更新所有行的another_variable="another"
列(这是唯一的,不能有两行(“ tgh“,”另一个“)对。虽然可以(”tgh“,”another2“)。)CURRENT_TIMESTAMP
。
因此,“选择”查询未完全匹配后,示例行将为(1, "tgh", "pass", 0, CURRENT_TIMESTAMP, "another")
,。
为了更加明确,我试图避免在表格上仅使用username="tgh"
和another_variable="another"
运行额外更新,即根据select的结果update thetable set last_unsuccessful_login=CURRENT_TIMESTAMP where username="tgh" and another_variable="another";
。
2)更正用户/通行证
此外,如果所有三个username
和password
以及another_variable
匹配,这次我想将last_successful_login
设置为CURRENT_TIMESTAMP
。
这会使示例行`(1,“tgh”,“pass”,CURRENT_TIMESTAMP,0,“另一个”)
最有效的方法是什么?
答案 0 :(得分:1)
对您的问题的简短回答是否定的,SELECT语句不可能导致或触发更新。 (这里需要注意的是SELECT语句可以调用一个可以执行UPDATE的FUNCTION(MySQL存储程序)。)
您无法绕过发布UPDATE语句;必须从某个地方发出UPDATE语句,SELECT语句不能“触发”它。
可以让一个UPDATE语句根据密码列中的当前值检查提供的密码,并设置last_successful_login和last_unsuccessful_login列,例如:
UPDATE thetable
SET last_successful_login =
IF(IFNULL(password,'')='wrongpass',CURRENT_TIMESTAMP,0)
, last_unsuccessful_login =
IF(IFNULL(password,'')='wrongpass',0,CURRENT_TIMESTAMP)
WHERE username='tgh'
AND another_variable='another'
因此,您可以先发出UPDATE语句;然后发出SELECT语句。
如果您想最大限度地减少数据库“往返”的数量,以增加复杂性为代价(让其他人更难弄清楚发生了什么),您可以将UPDATE语句放入存储的程序中。如果将其放入函数中,则可以设置返回值以指示登录是否成功。
SELECT udf_login('username','wrongpass','another')
因此,从您的应用程序看,您看起来正在进行登录检查,但被调用的函数可以执行更新。
CREATE FUNCTION `udf_login`
( as_username VARCHAR(30)
, as_password VARCHAR(30)
, as_another_variable VARCHAR(30)
) RETURNS INT
READS SQL DATA
BEGIN
UPDATE `thetable`
SET `last_successful_login` =
IF(IFNULL(`password`,'')=IFNULL(as_password,''),CURRENT_TIMESTAMP,0)
, `last_unsuccessful_login` =
IF(IFNULL(`password`,'')=IFNULL(as_password,''),0,CURRENT_TIMESTAMP)
WHERE `username` = as_username
AND `another_variable` = as_another_variable;
-- then perform whatever checks you need to (e.g)
-- SELECT IFNULL(t.password,'')=IFNULL(as_password,'') AS password_match
-- FROM `thetable` t
-- WHERE t.username = as_username
-- AND t.another_variable = as_another_variable
-- and conditionally return a 0 or 1
RETURN 0;
END$$