SQLite 或 FMDB 无法找到包含某些字符的行

Posted

技术标签:

【中文标题】SQLite 或 FMDB 无法找到包含某些字符的行【英文标题】:SQLite or FMDB is not able to find rows with certain characters 【发布时间】:2014-12-03 19:57:58 【问题描述】:

我遇到了一个问题,我试图将行插入到数据库中,前提是它们不存在。如果我插入某些字符,则 FMDB 或 SQLite 会出现问题并假设每一行都是新的:

我希望每个集合都插入第一条记录,然后更新它:

2014-12-03 14:50:32.554 Dapper[94814:1592610] SET 0
2014-12-03 14:50:32.554 Dapper[94814:1592610] Inserted a record for an item found in iTunes: KeyItemWith PI Π.M4A 1416284085 
2014-12-03 14:50:32.555 Dapper[94814:1592610] Updated a record for an item found in iTunes: KeyItemWith PI Π.M4A 1416284085 
2014-12-03 14:50:32.556 Dapper[94814:1592610] SET 1
2014-12-03 14:50:32.556 Dapper[94814:1592610] Inserted a record for an item found in iTunes: /Volumes/X5 TF1/Radwimps/New/08 Π.M4A 1416284085 
2014-12-03 14:50:32.557 Dapper[94814:1592610] Updated a record for an item found in iTunes: /Volumes/X5 TF1/Radwimps/New/08 Π.M4A 1416284085 
2014-12-03 14:50:32.558 Dapper[94814:1592610] SET 2
2014-12-03 14:50:32.571 Dapper[94814:1592610] Inserted a record for an item found in iTunes: /Volumes/X5 TF1/Radwimps/New/08 NEW.M4A 1416284085 
2014-12-03 14:50:32.574 Dapper[94814:1592610] Updated a record for an item found in iTunes: /Volumes/X5 TF1/Radwimps/New/08 NEW.M4A 1416284085 

但我得到了(注意设置 1、2 失败,设置 3 很好):

2014-12-03 14:50:32.554 Dapper[94814:1592610] SET 0
2014-12-03 14:50:32.554 Dapper[94814:1592610] Inserted a record for an item found in iTunes: KeyItemWith PI Π.M4A 1416284085 
2014-12-03 14:50:32.555 Dapper[94814:1592610] Inserted a record for an item found in iTunes: KeyItemWith PI Π.M4A 1416284085 
2014-12-03 14:50:32.556 Dapper[94814:1592610] SET 1
2014-12-03 14:50:32.556 Dapper[94814:1592610] Inserted a record for an item found in iTunes: /Volumes/X5 TF1/Radwimps/New/08 Π.M4A 1416284085 
2014-12-03 14:50:32.557 Dapper[94814:1592610] Inserted a record for an item found in iTunes: /Volumes/X5 TF1/Radwimps/New/08 Π.M4A 1416284085 
2014-12-03 14:50:32.558 Dapper[94814:1592610] SET 2
2014-12-03 14:50:32.571 Dapper[94814:1592610] Inserted a record for an item found in iTunes: /Volumes/X5 TF1/Radwimps/New/08 NEW.M4A 1416284085 
2014-12-03 14:50:32.574 Dapper[94814:1592610] Updated a record for an item found in iTunes: /Volumes/X5 TF1/Radwimps/New/08 NEW.M4A 1416284085 

代码如下:

#import "AppDelegate.h"
#import "FMDB.h"

@implementation AppDelegate

FMDatabase *leftDB;
FMDatabase *rightDB;

-(void)deleteDB




    NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
    NSString *dapperDirectory=@"/Users/jeremylaurenson/Desktop/";
    NSString *dapperDB=[dapperDirectory stringByAppendingPathComponent:@"dapperleft.sqlite"];

    NSLog(@"Deleting database at %@",dapperDB);

    [fileManager removeItemAtPath:dapperDB error:nil];

    dapperDB=[dapperDirectory stringByAppendingPathComponent:@"dapperright.sqlite"];

    NSLog(@"Deleting database at %@",dapperDB);

    [fileManager removeItemAtPath:dapperDB error:nil];


    [self openDB:1];
    [self createTable:1];
    [self closeDB:1];







-(void)openDB:(int)side

    FMDatabase *db;

    NSString *dapperDirectory=@"/Users/jeremylaurenson/Desktop/";
    NSString *dapperDB;
    if(side==1)dapperDB=[dapperDirectory stringByAppendingPathComponent:@"dapperleft.sqlite"];
    if(side==2)dapperDB=[dapperDirectory stringByAppendingPathComponent:@"dapperright.sqlite"];


    NSLog(@"Opening database at %@",dapperDB);
    db = [FMDatabase databaseWithPath:dapperDB];
    if (![db open]) 
        NSLog(@"Could not open db.");
    

    if(side==1)leftDB=db;
    if(side==2)rightDB=db;





-(void)createTable:(int)side

    FMDatabase *db;
    if(side==1)db=leftDB;
    if(side==2)db=rightDB;


    [db executeUpdate:@"CREATE TABLE `items` (     `key`    TEXT, `filepath`    TEXT,   `sourceFile` TEXT, `UUID`   TEXT,     `DAPsize` NUMERIC,     `OSXsize`  REAL,     `DAPdate` NUMERIC,     `OSXdate`  NUMERIC,     `MustUpdate` INTEGER,     `MustDelete` INTEGER     , `isOnDAP` INTEGER , `SandBoxBookMark` TEXT,`tombStone` INTEGER);"];









-(BOOL)zeroDatabase:(int)side


    FMDatabase *db;
    if(side==1)db=leftDB;
    if(side==2)db=rightDB;


    if(![db open])
        NSLog(@"DB is closed. Can not zero out");

        return FALSE;
    

    NSLog(@"Clearing flags in the database");

    [db executeUpdate:@"update `items` set MustDelete=0,MustUpdate=0,tombStone=1"];
    if([db hadError])
        NSLog(@"Database error");
        return FALSE;
    
    NSLog(@"Done clearing flags in the database");
    return TRUE;



-(void)closeDB:(int)side


    FMDatabase *db;
    if(side==1)db=leftDB;
    if(side==2)db=rightDB;


    if(![db open])
        [db close];

    







-(void)insertItemFromiTunes:(NSString *)dapPath withSource:(NSString *)sourcePath withSize:(NSNumber *)size withDate:(NSDate *)date withUUID:(NSString *)UUID  withSide:(int)side withSandboxBookmark:(NSString *)bookmark

    FMDatabase *db;
    if(side==1)db=leftDB;
    if(side==2)db=rightDB;

    BOOL updateOperation=FALSE;

    if(![db open])
        NSLog(@"DB is closed. Can not insertitemfromOSX");
        return;
    
    NSNumber *convertedDate=[NSNumber numberWithDouble:[date timeIntervalSince1970]];



    FMResultSet *results = [db executeQuery:@"select count(*) from `items` where lower(key) = lower(?)",dapPath,nil];
    while([results next])
    
        if([results unsignedLongLongIntForColumnIndex:0]>0)

            updateOperation=TRUE;
        

    
    [results close];

    if(updateOperation)
        NSLog(@"Updated a record for an item found in iTunes: %@ %@ ",dapPath,size);

        [db executeUpdate:@"update `items` set OSXsize=?, OSXDate=?, UUID=?,sourceFile=?,tombStone=0,SandBoxBookMark=? where lower(key)=lower(?)",
         size,convertedDate,UUID,sourcePath,bookmark,dapPath, nil];


    
    else
    
        NSLog(@"Inserted a record for an item found in iTunes: %@ %@ ",dapPath,size);

        [db executeUpdate:@"insert into `items`(key,filepath, OSXsize, OSXdate,UUID,sourceFile,tombStone,SandBoxBookMark) values(?,?,?,?,?,?,0,?)",
         [dapPath lowercaseString], dapPath, size,convertedDate,UUID,sourcePath,bookmark,nil];

    





- (void)applicationWillFinishLaunching:(NSNotification *)aNotification 
    // Offer to the move the Application if necessary.
    // Note that if the user chooses to move the application,
    // this call will never return. Therefore you can suppress
    // any first run UI by putting it after this call.




- (void)applicationWillTerminate:(NSNotification *)aNotification

    [self closeDB:1];
    [self closeDB:2];







- (void)applicationDidFinishLaunching:(NSNotification *)aNotification



    [self deleteDB];;
    [self openDB:1];


    NSLog(@"SET 0");
    [self insertItemFromiTunes:@"KeyItemWith PI Π.M4A" withSource:@"Some Pie.m4a" withSize:[NSNumber numberWithInt:1416284085] withDate:[NSDate date] withUUID:nil withSide:1 withSandboxBookmark:@"PiePieIs PI"];


    [self insertItemFromiTunes:@"KeyItemWith PI Π.M4A" withSource:@"Some Pie.m4a" withSize:[NSNumber numberWithInt:1416284085] withDate:[NSDate date] withUUID:nil withSide:1 withSandboxBookmark:@"PiePieIs PI"];






    NSLog(@"SET 1");
    [self insertItemFromiTunes:@"/Volumes/X5 TF1/Radwimps/New/08 Π.M4A" withSource:@"file:///Users/jeremylaurenson/Music/iTunes/iTunes%20Media/Music/RADWIMPS/%E7%B5%B6%E4%BD%93%E7%B5%B6%E5%91%BD/08%20%CF%80.m4a" withSize:[NSNumber numberWithInt:1416284085] withDate:[NSDate date] withUUID:nil withSide:1 withSandboxBookmark:@"file:///Users/jeremylaurenson/Music/iTunes/iTunes%20Media/Music/RADWIMPS/%E7%B5%B6%E4%BD%93%E7%B5%B6%E5%91%BD/08%20%CF%80.m4a"];



    [self insertItemFromiTunes:@"/Volumes/X5 TF1/Radwimps/New/08 Π.M4A" withSource:@"file:///Users/jeremylaurenson/Music/iTunes/iTunes%20Media/Music/RADWIMPS/%E7%B5%B6%E4%BD%93%E7%B5%B6%E5%91%BD/08%20%CF%80.m4a" withSize:[NSNumber numberWithInt:1416284085] withDate:[NSDate date] withUUID:nil withSide:1 withSandboxBookmark:@"file:///Users/jeremylaurenson/Music/iTunes/iTunes%20Media/Music/RADWIMPS/%E7%B5%B6%E4%BD%93%E7%B5%B6%E5%91%BD/08%20%CF%80.m4a"];


    NSLog(@"SET 2");


    [self insertItemFromiTunes:@"/Volumes/X5 TF1/Radwimps/New/08 NEW.M4A" withSource:@"file:///Users/jeremylaurenson/Music/iTunes/iTunes%20Media/Music/RADWIMPS/%E7%B5%B6%E4%BD%93%E7%B5%B6%E5%91%BD/08%20%CF%80.m4a" withSize:[NSNumber numberWithInt:1416284085] withDate:[NSDate date] withUUID:nil withSide:1 withSandboxBookmark:@"file:///Users/jeremylaurenson/Music/iTunes/iTunes%20Media/Music/RADWIMPS/%E7%B5%B6%E4%BD%93%E7%B5%B6%E5%91%BD/08%20%CF%80.m4a"];



    [self insertItemFromiTunes:@"/Volumes/X5 TF1/Radwimps/New/08 NEW.M4A" withSource:@"file:///Users/jeremylaurenson/Music/iTunes/iTunes%20Media/Music/RADWIMPS/%E7%B5%B6%E4%BD%93%E7%B5%B6%E5%91%BD/08%20%CF%80.m4a" withSize:[NSNumber numberWithInt:1416284085] withDate:[NSDate date] withUUID:nil withSide:1 withSandboxBookmark:@"file:///Users/jeremylaurenson/Music/iTunes/iTunes%20Media/Music/RADWIMPS/%E7%B5%B6%E4%BD%93%E7%B5%B6%E5%91%BD/08%20%CF%80.m4a"];





    [self closeDB:1];
    [[NSApplication sharedApplication] terminate:self];


【问题讨论】:

【参考方案1】:

我将小写转换全部转换为可可,因此 SQL 没有执行 lower() 调用。修复了问题。

【讨论】:

以上是关于SQLite 或 FMDB 无法找到包含某些字符的行的主要内容,如果未能解决你的问题,请参考以下文章

FMDB之数组字典的存储

FMDB,sqlite json-string 成字典?

SQLite FMDB 创建表 - 初学者 iOS

IOS_FMDB有关字典数组存储及获取问题

iOS的SQLite利用FMDB进行操作时无法打开数据库

FMDB 如何让 sqlite 更简单 iOS?