SQLite中是否有像FOR .. in .. LOOP
或类似的东西的循环语句?我有两列StartRange, EndRange
,我需要在其他表中插入整个序列。因此,如果StartRange
为1且EndRange
为3,则需要制作三个带有值的插入,其中包含1, 2, 3
。SQLite循环语句?
回答
如果你有一个额外的表,它包含你需要的所有整数,你可以在直接SQL中做这种事情。
假设一个十之间的StartRange
和EndRange
范围内,你有一个表是这样的:
sqlite> select i from ints;
i
1
.
.
.
10
此表只是包含了所有你需要的可能的整数(即1到10)。
然后,如果你也有这样的:
sqlite> create table t (startrange int not null, endrange int not null);
sqlite> insert into t values(1, 3);
sqlite> create table target (i int not null);
你可以做你插入到target
与联接:
insert into target (i)
select ints.i
from ints join t on (ints.i >= t.startrange and ints.i <= t.endrange)
结果是这样的:
sqlite> select * from target;
i
1
2
3
当然你的真实t
将有更多的行,所以你想要一个WHERE子句来限制哪一行t
你看。
类似的事情通常与日期(查找“日历表”)。
所以,如果你的范围小(对于小一些定义),然后生成您的ints
表一次,一个索引添加到它,并使用上述技术做对数据库内的所有插件。其他数据库有自己的方式(如PostgreSQL的generate_series
)做这种事情,而不需要明确的ints
表,但SQLite(有意)是有限的。
SQL通常是基于集合的,所以循环并不自然。很自然的是通过描述你需要的东西来构建适当的集合。 OTOH,有时不自然的行为是必要和明智的。
我不知道这对你的应用程序是否有意义,我只是想我会证明它是如何完成的。如果这种方法在你的情况下没有意义,那么你可以在数据库之外生成一堆INSERT语句。
SQLite表具有可用于查询的行号。 – reinierpost
@reinierpost你指的是'rowid'吗? –
是的。 (和你的名字,它*仍然*太短) – reinierpost
您可以使用递归触发器在SQL中创建循环。使用亩太短的架构
sqlite> create table t (startrange int not null, endrange int not null);
sqlite> insert into t values(1, 3);
sqlite> create table target (i int not null);
,我们需要启用SQLite的递归触发器:
sqlite> PRAGMA recursive_triggers = on;
创建一个临时触发循环到范围的末尾:
sqlite> create temp trigger ttrig
...> before insert on target
...> when new.i < (select t.endrange from t) begin
...> insert into target values (new.i + 1);
...> end;
踢开它:
sqlite> insert into target values ((select t.startrange from t));
sqlite> select * from target;
3
2
1
sqlite>
这是我需要的黑魔法。谢谢哥们! –
显然,SQLite中的循环结构是WITH RECURSIVE子句。 该文档链接包含样本计数到十位的代码,一个Mandelbrot设置绘图仪和一个Sudoku拼图求解器,都在纯SQL中。 下面是计算斐波那契序列的SQLite的查询,给你的感觉吧:
sqlite> WITH RECURSIVE
...> fibo (curr, next)
...> AS
...> (SELECT 1,1
...> UNION ALL
...> SELECT next, curr+next FROM fibo
...> LIMIT 100)
...> SELECT group_concat(curr) FROM fibo;
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,...
这里是一个Sieve of Eratosthenes:
begin transaction;
drop table if exists naturals;
create table naturals
(n integer unique primary key asc,
isprime bool,
factor integer);
with recursive
nn (n)
as (
select 2
union all
select n+1 as newn from nn
where newn < 1e4
)
insert into naturals
select n, 1, null from nn;
insert or replace into naturals
with recursive
product (prime,composite)
as (
select n, n*n as sqr
from naturals
where sqr <= (select max(n) from naturals)
union all
select prime, composite+prime as prod
from
product
where
prod <= (select max(n) from naturals)
)
select n, 0, prime
from product join naturals
on (product.composite = naturals.n)
;
commit;
- 1. 循环while语句
- 2. Javascript语句循环内if语句
- 3. jquery循环条件语句
- 4. if语句或循环
- 5. python while循环break语句
- 6. AS3循环IF语句
- 7. Javascript while while语句循环
- 8. While循环与if语句
- 9. while循环,开关语句
- 10. 循环和条件语句
- 11. 直到语句/循环python?
- 12. 如果语句内循环
- 13. For循环和if语句
- 14. return语句for循环
- 15. For循环和if语句
- 16. if语句while循环JAVA
- 17. 虽然循环语句
- 18. for循环和if语句
- 19. PHP循环语句问题
- 20. 使用SQL语句循环
- 21. 的循环语句笨
- 22. 直到循环if语句
- 23. if循环内的语句
- 24. 循环切换语句
- 25. For循环/ if语句java
- 26. 循环语句逻辑
- 27. 循环SQL语句插入
- 28. 通过switch语句循环
- 29. While循环和if语句
- 30. for循环,如果语句
恐怕你需要编写一些必要的代码,这样做它通常是一种声明性语言,只有它的扩展(如T-SQL,SQL/PL等)支持循环等控制流结构。但是,如果应该很容易,可以使用SQLite事务在一次运行中执行插入操作。 –
Perl/Python/Ruby-script-to-the-rescue! :) – 2011-09-10 09:17:07
这应该被移动到dba.stackexchange.com? – anddam