我在MySQL中存储函数时遇到了相当令人沮丧的问题。
我有一个数据库,其中包含来自连接到无线热点的用户的会话数据。我试图从选定的月份内选择单个用户下载统计信息。我的问题是函数中的子查询似乎忽略了WHERE语句中的mac
字段。这是我的代码:
CREATE FUNCTION get_month_download(mo varchar(45), box int(11), mac varchar(45)) RETURNS DOUBLE
BEGIN
DECLARE dwnld double;
IF mo IS NULL THEN
SET mo := CONCAT(CONCAT(YEAR(NOW()), '-', MONTH(NOW())),'-','01');
END IF;
SET dwnld := (
SELECT SUM(`tx_bytes`)
FROM `session`
WHERE `assoc_time` > UNIX_TIMESTAMP(mo)
AND `disassoc_time` < UNIX_TIMESTAMP(DATE_ADD(mo, INTERVAL 1 MONTH))
AND `mac` = mac
AND `controller_id` = box
);
return dwnld;
END
运行此:
SELECT get_month_download('2012-09-01', '2', '00:21:5c:56:be:a3');
返回整个表的下载数据,尽管它使用controller_id
来过滤数据。
如果我使用相同的参数在函数外部运行子查询,它可以正常工作。是什么给了什么?
更清楚一点,运行此查询:
SELECT SUM(`tx_bytes`)
FROM `session`
WHERE `assoc_time` > UNIX_TIMESTAMP('2012-09-01')
AND `disassoc_time` < UNIX_TIMESTAMP(DATE_ADD('2012-09-01', INTERVAL 1 MONTH))
AND `mac` = '00:21:5c:56:be:a3'
AND `controller_id` = '2';
返回该用户的正确下载统计信息。函数返回该控制器的所有用户的统计信息。
答案 0 :(得分:1)
您确定存在多个controller_id
吗?
SELECT DISTINCT controller_id FROM session
此查询提取了多少条记录?
如果这只取一条记录,并且对应于box = 2,则没有问题。
如果有多个控制器ID,请运行此查询
SELECT COUNT(1), controller_id
FROM session
WHERE assoc_time > '2012-01-01'
AND disassoc_time < '2012-01-31'
AND mac = '00:21:5c:56:be:a3'
GROUP BY controller_id
这会返回多少行?如果它只返回controller_id 2的一条记录,则没有任何isssue。
答案 1 :(得分:1)
我应该回想一下我老师在大学里教我的经历。问题是,select语句范围内的变量mac
被视为表中的一个字段,而不是函数中的参数。因此,更改参数名称修复了问题:
CREATE FUNCTION get_month_download(mo varchar(45), box int(11), inmac varchar(60)) RETURNS DOUBLE
BEGIN
DECLARE dwnld double;
IF mo IS NULL THEN
SET mo := CONCAT(CONCAT(YEAR(NOW()), '-', MONTH(NOW())),'-','01');
END IF;
SET dwnld := (
SELECT SUM(`tx_bytes`)
FROM `session`
WHERE `assoc_time` > UNIX_TIMESTAMP(mo)
AND `disassoc_time` < UNIX_TIMESTAMP(DATE_ADD(mo, INTERVAL 1 MONTH))
AND `controller_id` = box
AND `mac` = inmac
);
return dwnld;
END
这是一个'面对面'的时刻。谢谢大家的帮助。