2013-12-23 144 views
2

我正在使用以下SQL查詢創建臨時表。但是,當我以編程方式執行它時沒有顯示任何結果(結果集爲空),並且在數據庫上手動執行它時顯示記錄。FMDB sqlite的SQL查詢不起作用

NSString *query=[NSString stringWithFormat:@"create temp table search2 as select Observationsid from Observations where admin_id=%d AND teacher_id=%d AND observation_type=%d AND isvalid='yes' AND date BETWEEN '12-20-2013' AND '12-23-2013'",appDelegate.admin_id,appDelegate.teacher_id,appDelegate.observationType]; 
FMResultSet *results=[appDelegate.database executeQuery:query]; 

Nslogged查詢:結果 印刷說明 - > _查詢:

create temp table search2 as select Observationsid from Observations where admin_id=2 AND teacher_id=1 AND observation_type=2 AND isvalid='yes' AND date BETWEEN '12-20-2013' AND '12-23-2013' 

和記錄有在數據庫中。

+0

不相關,但我注意到你的日期使用了「MM-DD-YYYY」格式。你真的想使用'YYYY-MM-DD',或者更好地依靠'FMDatabase'來爲你轉換你的'NSDate'值。但是如果你使用你所擁有的,'12-21-2052'的文本字符串是'BETWEEN '12 -20-2013'和'12 -23-2013',這可能不是你想要的。請記住,SQLite沒有適當的日期格式,所以選擇適當的格式(例如'YYYY-MM-DD'格式)或讓'FMDatabase'使用'NSDate'對象爲你處理。 – Rob

+0

@Rob非常感謝你。我對sqlite和nsdate的數據庫日期格式的日期格式有困惑,但我沒有努力提出問題。你會吹捧給我適當的例子或教程的鏈接,這將解釋更多關於這一點。提前致謝。 – ViruMax

+0

我已經添加了一些示例日期邏輯到我的答案結束。 – Rob

回答

0

此SQL語句不應該返回結果,因此您應該使用executeUpdate方法而不是executeQuery方法。你不應該看到這個結果。如果您想查看結果,請執行單獨的executeQuery聲明,返回search2的結果。 (我假設你正在構建的search2表的一個原因。)

NSString *query=[NSString stringWithFormat:@"create temp table search2 as select Observationsid from Observations where admin_id=%d AND teacher_id=%d AND observation_type=%d AND isvalid='yes' AND date BETWEEN '12-20-2013' AND '12-23-2013'",appDelegate.admin_id,appDelegate.teacher_id,appDelegate.observationType]; 
if (![appDelegate.database executeUpdate:query]) 
    NSLog(@"create error: %@", [appDelegate.database lastErrorMessage]); 

query = @"SELECT * FROM search2"; 
FMResultSet *results = [appDelegate.database executeQuery:query]; 
if (!results) 
    NSLog(@"create error: %@", [appDelegate.database lastErrorMessage]); 

順便說一句,而你可以逃脫stringWithFormat這個特定的SQL,這不是一個好主意。您通常希望使用?佔位符,例如

NSString *query = @"create temp table search2 as select Observationsid from Observations where admin_id=? AND teacher_id=? AND observation_type=? AND isvalid='yes' AND date BETWEEN '12-20-2013' AND '12-23-2013'"; 
if (![appDelegate.database executeUpdate:query, @(appDelegate.admin_id), @(appDelegate.teacher_id), @(appDelegate.observationType)]) 
    NSLog(@"create error: %@", [appDelegate.database lastErrorMessage]); 

無關,但我注意到你正在使用MM-DD-YYYY格式的文本字符串爲您的日期。這是行不通的。 SQLite本身不會「理解」日期。值得注意的是,如果您以MM-DD-YYYY格式存儲日期,則12-21-2052的文本字符串爲BETWEEN '12-20-2013' AND '12-23-2013'(因爲文本字符串按字母順序進行比較),這可能不是您想要的。見Date And Time Functions

但幸運的是,FMDB爲您做了NSDate轉換,並將其存儲爲數值。因此,舉例來說,假設你的表定義如下:

CREATE TABLE IF NOT EXISTS Observations 
    (Observationsid INTEGER PRIMARY KEY AUTOINCREMENT, 
    admin_id   INTEGER, 
    teacher_id  INTEGER, 
    observation_type INTEGER, 
    isvalid   TEXT, 
    date    REAL); 

你真的想用YYYY-MM-DD,或者更好,依靠FMDatabaseNSDate值轉換爲您服務。請記住,SQLite沒有適當的日期格式,因此請選擇適當的格式(例如YYYY-MM-DD格式)或讓FMDatabase使用NSDate對象爲您處理。

如果你想方便的日期字符串到日期的轉換,你可以使用一個NSDateFormatter,如:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
formatter.dateFormat = @"MM-dd-yyyy"; 

NSDate *someDate = [formatter dateFromString:@"12-22-2013"]; 
if (![appDelegate.database executeUpdate:@"INSERT INTO Observations (admin_id, teacher_id, observation_type, isvalid, date) VALUES (?, ?, ?, ?, ?)", @(appDelegate.admin_id), @(appDelegate.teacher_id), @(appDelegate.observationType), @"yes", someDate]) 
    NSLog(@"insert error: %@", [appDelegate.database lastErrorMessage]); 

或者,如果我要選擇這兩個日期之間的日期:

NSDate *startDate = [formatter dateFromString:@"12-20-2013"]; 
NSDate *endDate = [formatter dateFromString:@"12-23-2013"]; 

NSString *query = @"create temp table search2 as select Observationsid, date from Observations where admin_id=? AND teacher_id=? AND observation_type=? AND isvalid='yes' AND date BETWEEN ? AND ?"; 
if (![appDelegate.database executeUpdate:query, @(appDelegate.admin_id), @(appDelegate.teacher_id), @(appDelegate.observationType), startDate, endDate]) 
    NSLog(@"create error: %@", [appDelegate.database lastErrorMessage]); 

query = @"SELECT * FROM search2"; 
FMResultSet *results = [appDelegate.database executeQuery:query]; 
if (!results) 
    NSLog(@"select error: %@", [appDelegate.database lastErrorMessage]); 
while ([results next]) 
    NSLog(@"%d %@", [results intForColumnIndex:0], [results dateForColumnIndex:1]); 

如果你想避免這個NSDate邏輯,你可以有選擇地有意識地以YYYY-MM-DD格式存儲文本格式的日期。這也適用。同樣,請參閱Date and Time Functions頁面以獲取日期的有效文本格式列表。

+0

非常感謝。 :)。我也在嘗試FMResultSet * results = [appDelegate.database executeUpdate:query];但我使用FMResultSet,因此它給錯誤。 – ViruMax

+0

是的,一個問題是我不知道,sqlite存儲日期數字格式,它由FMDatabase自動處理。 – ViruMax