作者:s350350350 | 来源:互联网 | 2023-05-17 22:10
IverunintoacasewhereasqlitequeryImexpectingtoreturnanerrorisactuallysucceedingan
I've run into a case where a sqlite query I'm expecting to return an error is actually succeeding and I was wondering if anyone could point out why this query is valid.
我遇到一个案例,我希望返回错误的sqlite查询实际上是成功的,我想知道是否有人可以指出为什么这个查询是有效的。
CREATE TABLE test_table(
k INTEGER,
v INTEGER
);
INSERT INTO test_table( k, v ) VALUES( 4, 5 );
SELECT * FROM(
SELECT * FROM(
SELECT k, v FROM test_table WHERE 1 = 0
)
UNION ALL
SELECT * FROM(
SELECT rowid, k, v FROM test_table
)
)
sqlfiddle of above
上面的方块
I would think that unioning two selects which have a different number of columns would return an error. If I remove the outermost SELECT *
then I receive the error I'm expecting: SELECTs to the left and right of UNION ALL do not have the same number of result columns
.
我认为联合两个具有不同列数的选择将返回错误。如果我删除最外面的SELECT *然后我收到我期望的错误:UNION ALL左侧和右侧的SELECT没有相同数量的结果列。
2 个解决方案
10
The answer to this seems to be straightforward: Yes, this is a quirk. I'd like to demonstrate this with a short example. But beforehand, let's consult the documentation:
答案似乎很简单:是的,这是一个怪癖。我想用一个简短的例子来证明这一点。但事先,让我们查阅文档:
Two or more simple SELECT statements may be connected together to form a compound SELECT using the UNION, UNION ALL, INTERSECT or EXCEPT operator. In a compound SELECT, all the constituent SELECTs must return the same number of result columns.
可以使用UNION,UNION ALL,INTERSECT或EXCEPT运算符将两个或多个简单SELECT语句连接在一起以形成复合SELECT。在复合SELECT中,所有组成SELECT必须返回相同数量的结果列。
So the documentations says very clearly that two SELECTs
must provide the same number of columns. However, as you said, the outermost SELECT
strangely avoids this 'limitation'.
因此,文档非常清楚地说明两个SELECT必须提供相同数量的列。但是,正如你所说,最外面的SELECT奇怪地避免了这种“限制”。
Example 1
例1
SELECT * FROM(
SELECT k, v FROM test_table
UNION ALL
SELECT k, v,rowid FROM test_table
);
Result:
结果:
k|v
4|5
4|5
The third column rowid
gets simply omitted, as pointed out in the comments.
正如评论中所指出的那样,第三列rowid被简单地省略了。
Example 2
例2
We are only switching the order of the two select statements.
我们只是切换两个select语句的顺序。
SELECT * FROM(
SELECT k, v, rowid FROM test_table
UNION ALL
SELECT k, v FROM test_table
);
Result
结果
k|v|rowid
4|5|1
4|5|
Now, sqlite does not omit the column but add a null value.
现在,sqlite不会省略列但添加空值。
Conclusion
结论
This brings me to my conclusion, that sqlite simply handles the UNION ALL
differently if it is processed as a subquery.
这让我得出结论,如果将sqlite作为子查询处理,它将简单地处理UNION ALL。
PS: If you are just using UNION
it fails at any scenario.
PS:如果您只是使用UNION,它在任何情况下都会失败。