10

我正在使用这个有错误的代码:

SET @rejects = '';

SELECT *
FROM list
WHERE maker = 1
    AND by_ids IN ('10','11')
    AND country LIKE '%I%'
    AND (
        src IS NULL
        || src NOT IN (@rejects)
        AND checkSrc(src) = 'yes'
        AND SET @rejects = CONCAT(@rejects,',',src)
    );

是什么导致了这个问题?

4

2 回答 2

15

问题是你不能混用selectset在一个语句中,肯定会有语法错误:

select*from t where 1 and set@a=1;

ERROR 1064 (42000):您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的 'set@a=1' 附近使用正确的语法

如果要在set范围内执行select,请使用冒号等于语法。改变这个:

select*from t where 1 and set@a=1;

进入:

select*,@a:=1 from t where 1;

以下是在每一行更新变量的方法:

create table t(id int); insert t values(1),(2),(3);
set@a=0;
select@a:=id from t;
+--------+
| @a:=id |
+--------+
|      1 |
|      2 |
|      3 |
+--------+

你甚至可以这样做concat

set@a='0';
select @a:=concat(@a,',',id)from t;
+-----------------------+
| @a:=concat(@a,',',id) |
+-----------------------+
| 0,1                   |
| 0,1,2                 |
| 0,1,2,3               |
+-----------------------+

或者concat没有前导0

set@a='';
select @a:=concat(@a,if(@a='','',','),id)from t;
+------------------------------------+
| @a:=concat(@a,if(@a='','',','),id) |
+------------------------------------+
| 1                                  |
| 1,2                                |
| 1,2,3                              |
+------------------------------------+

但是,该手册明确指出这是危险的:关联

...您永远不应为用户变量赋值并在同一语句中读取该值...

...您可能会得到您期望的结果,但这不能保证

...涉及用户变量的表达式的求值顺序是 undefined

Xaprb上也提到了这一点。

最后,如果您正在做一些古怪的事情,例如为变量分配不同的值类型等,请查看手册以确保您了解复杂的机制。

于 2015-04-01T13:16:45.920 回答
2

然后你可以这样写你的查询。

SET @rejects = '';
SELECT @rejects = CONCAT(@rejects,',',src) FROM list WHERE maker = 1 AND by_ids IN ('10','11') AND country LIKE '%I%' AND 
(src IS NULL OR src NOT IN (@rejects) AND checkSrc(src) = 'yes');
SELECT @rejects;
于 2013-03-22T22:50:26.153 回答