2011-09-10 11 views
15

क्या SQLite में FOR .. in .. LOOP या ऐसा कुछ भी है? मेरे पास दो कॉलम StartRange, EndRange हैं और मुझे अन्य तालिका में संपूर्ण अनुक्रम डालने की आवश्यकता है। तो यदि StartRange 1 और EndRange 3 है, तो मूल्य के साथ तीन आवेषण करना आवश्यक है, इसमें 1, 2, 3 शामिल है।SQLite लूप स्टेटमेंट्स?

+2

मुझे डर है कि तुम क्या करने के लिए कुछ जरूरी कोड लिखने की आवश्यकता होगी कर रहा हूँ यह, एसक्यूएल आम तौर पर एक घोषणात्मक भाषा है और केवल इसके एक्सटेंशन (जैसे टी-एसक्यूएल, एसक्यूएल/पीएल इत्यादि) समर्थन नियंत्रण प्रवाह संरचना जैसे लूप। हालांकि, आसान होना चाहिए, हालांकि, SQLite लेनदेन का उपयोग कर एक रन में सम्मिलन करने के लिए। –

+0

पर्ल/पायथन/रुबी-स्क्रिप्ट-टू-द-बचाव! :) –

+0

क्या इसे dba.stackexchange.com पर ले जाया जाना चाहिए? – anddam

उत्तर

8

यदि आप एक अतिरिक्त टेबल है जिसमें आपको आवश्यक सभी पूर्णांक रखने वाले अतिरिक्त तालिका में आप इस तरह की चीज सीधे एसक्यूएल में कर सकते हैं।

एक और दस के बीच अपने StartRange और EndRange सीमा मान लीजिए और आप एक मेज इस तरह:

sqlite> select i from ints; 
i 
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 में अपने आवेषण कर सकते हैं एक में शामिल होने:

sqlite> select * from target; 
i 
1 
2 
3 
बेशक

:

insert into target (i) 
select ints.i 
from ints join t on (ints.i >= t.startrange and ints.i <= t.endrange) 

परिणाम यह है आपके वास्तविक t में और पंक्तियां होंगी ताकि आप एक पंक्ति अनुभाग को सीमित करने के लिए WHERE क्लॉज चाहें t पर आप देखें।

इसी तरह की चीजें अक्सर तिथियों के साथ की जाती हैं ("कैलेंडर टेबल" देखें)।

तो अपने पर्वतमाला (छोटे के कुछ परिभाषा के लिए) छोटे हैं तो, एक बार अपने ints तालिका उत्पन्न इसे करने के लिए एक सूचकांक जोड़ सकते हैं और इसके बाद के संस्करण तकनीक का उपयोग सही डेटाबेस के अंदर सभी आवेषण क्या करना है। अन्य डेटाबेस के पास अपने तरीके हैं (जैसे PostgreSQL के generate_series) इस प्रकार की चीज़ को स्पष्ट ints तालिका के बिना करने के लिए, लेकिन SQLite (जानबूझकर) सीमित है।

एसक्यूएल आम तौर पर सेट-आधारित होता है इसलिए लूप प्राकृतिक नहीं होते हैं। प्राकृतिक क्या है जो आपको आवश्यकतानुसार वर्णन करके उचित सेट का निर्माण कर रहा है। ओटीओएच, कभी-कभी अप्राकृतिक कृत्य आवश्यक और समझदार होते हैं।

मुझे नहीं पता कि यह आपके आवेदन के लिए समझ में आता है, मैंने सोचा कि मैं दिखाऊंगा कि यह कैसे किया जा सकता है। यदि यह दृष्टिकोण आपके मामले में समझ में नहीं आता है तो आप डेटाबेस के बाहर INSERT कथन का एक समूह उत्पन्न कर सकते हैं।

+0

SQLite टेबल में पंक्ति संख्याएं हैं जिनका उपयोग क्वेरी में किया जा सकता है। – reinierpost

+0

@reinierpost क्या आप 'rowid' का जिक्र कर रहे हैं? –

+0

हां। (और आपके नाम के साथ, यह * अभी भी बहुत छोटा है) – reinierpost

14

आप रिकर्सिव ट्रिगर्स के साथ एसक्यूएल में लूप बना सकते हैं।म्यू का उपयोग करना बहुत छोटा

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> 
+2

यहां मुझे आवश्यक काला जादू है। धन्यवाद दोस्त! –

2

स्पष्ट रूप से SQLite में लूपिंग निर्माण WITH RECURSIVE खंड है। उस प्रलेखन लिंक में नमूना-से-दस कोड, मंडलब्रॉट सेट प्लॉटटर और एक सुडोकू पहेली सॉल्वर है, सभी शुद्ध 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;