Dou*_*rie 19
您可以使用递归触发器在SQL中创建循环.使用mu太短的架构
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);
Run Code Online (Sandbox Code Playgroud)
我们需要在SQLite中启用递归触发器:
sqlite> PRAGMA recursive_triggers = on;
Run Code Online (Sandbox Code Playgroud)
制作一个临时触发器以循环到范围的末尾:
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;
Run Code Online (Sandbox Code Playgroud)
开始吧:
sqlite> insert into target values ((select t.startrange from t));
sqlite> select * from target;
3
2
1
sqlite>
Run Code Online (Sandbox Code Playgroud)
mu *_*ort 11
如果你有一个包含你需要的所有整数的额外表,你可以在直接SQL中执行此类操作.
假设你StartRange和EndRange一个十之间的范围,你有这样的一个表:
sqlite> select i from ints;
i
1
.
.
.
10
Run Code Online (Sandbox Code Playgroud)
该表只包含您需要的所有可能的整数(即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);
Run Code Online (Sandbox Code Playgroud)
您可以使用联接进行INSERT target:
insert into target (i)
select ints.i
from ints join t on (ints.i >= t.startrange and ints.i <= t.endrange)
Run Code Online (Sandbox Code Playgroud)
结果是这样的:
sqlite> select * from target;
i
1
2
3
Run Code Online (Sandbox Code Playgroud)
当然你的真实t会有更多行,所以你想要一个WHERE子句来限制t你看哪一行.
类似的事情通常用日期来完成(查找"日历表").
因此,如果范围很小(对于某些小的定义),则生成ints一次表,为其添加索引,并使用上述技术在数据库内部执行所有INSERT.其他数据库有自己的方式(比如PostgreSQL generate_series)来做这种事情而不需要显式ints表,但SQLite(故意)有限.
SQL通常是基于集合的,因此循环不自然.通过描述您的需求来构建适当的集合是很自然的.OTOH,有时不自然的行为是必要和明智的.
我不知道这对你的应用程序是否有意义,我只是想我会演示它是如何完成的.如果这种方法在您的情况下没有意义,那么您可以在数据库外生成一堆INSERT语句.
显然,SQLite中的循环结构是WITH RECURSIVE子句.该文档链接包含样本数到十的代码,一个Mandelbrot set plotter和一个Sudoku难题解算器,所有这些都在纯SQL中.这是一个SQLite查询,它计算Fibonacci序列,让您感受到它:
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,...
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
46116 次 |
| 最近记录: |