Вопрос по iphone, sqlite, ios – Создание файла базы данных SQLite3 через Objective-C

5

Я пытаюсь создать файл базы данных SQLite3 через Objective-C во время выполнения. Я пытаюсь создать таблицу с именем & quot; tblStore & quot ;. Я хочу, чтобы имена полей были названы & quot; strStoreNumber & quot; и & quot; strStoreReg & quot ;. Я новичок в iOS и SQLite, поэтому мне сложно найти синтаксис для этого. В дополнение к созданию таблицы, я хочу, чтобы созданная таблица находилась НЕ в комплекте приложений, а скорее, чтобы она находилась / сохранялась где-то на телефоне. Таблица должна быть читаемой / записываемой. Я прочитал "пользовательскую песочницу" а также «каталог документов». Я не уверен, что понимаю разницу между ними. В идеале мое приложение будет использовать кнопку для ввода данных из текстовых полей. После того, как входные данные из текстовых полей помещены в строки, будет выполнена проверка, чтобы убедиться, что мой & quot; tblStore & quot; Таблица SQLite существует, и если ее нет, таблица будет создана.

Подведем итог: 1. Каков синтаксис для Obj-C / SQLite для создания таблицы с именем & quot; tblStore & quot; с полями & quot; strStoreNumber & quot; и & quot; strStoreReg & quot ;? 2. Где должен находиться файл db? Мне нужно прочитать и записать в файл tblStore db. 3. В чем разница между «пользовательской песочницей»? и «каталог документов»?

Вот что у меня сейчас:

<code>-(IBAction)setInput:(id)sender
{
    NSString *strStoreNumber;
    NSString *strRegNumber;
    NSString *tableName = @"tblStore";
    NSString *dbStrStore = @"strStore";
    NSString *dbStrReg = @"strReg";


    strStoreNumber = StoreNumber.text;
    strRegNumber = RegNumber.text;

    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* documentsDirectory = [paths lastObject];
    NSString* databasePath = [documentsDirectory stringByAppendingPathComponent:@"tblStore.sqlite"];
//  NSString* databasePath = [[NSBundle mainBundle] pathForResource:@"tblStore" ofType:@"sqlite"];

    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) 
    {
        NSLog(@"Opened sqlite database at %@", databasePath);

        char *err; 
        NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS '%@' ('%@' TEXT PRIMARY KEY, '%@' TEXT);", tableName, dbStrStore, dbStrReg];
        if (sqlite3_exec(database, [sql UTF8String], NULL, NULL, &err) != SQLITE_OK) 
        { 
            sqlite3_close(database);
            NSAssert(0, @"Table failed to create.");
        }
        //...stuff
    } 
    else 
    {
        NSLog(@"Failed to open database at %@ with error %s", databasePath, sqlite3_errmsg(database));
        sqlite3_close (database);
    }

    NSString *querystring;

    // create your statement
    querystring = [NSString stringWithFormat:@"SELECT strStore, strReg FROM tblStore WHERE strStore = %@ AND strReg = %@;", strStoreNumber, strRegNumber];  

    const char *sql = [querystring UTF8String];

    NSString *szStore = nil;
    NSString *szReg = nil;

    sqlite3_stmt *statement = nil;
    if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL)!=SQLITE_OK) //queryString = Statement
    {
        NSLog(@"sql problem occured with: %s", sql);
        NSLog(@"%s", sqlite3_errmsg(database));
    }
    else
    {
        // you could handle multiple rows here
        while (sqlite3_step(statement) == SQLITE_ROW) 
        {            
            szStore = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)];
            szReg = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)];
        }        
    }

    sqlite3_finalize(statement);

    lblStoreNumber.text = szStore;
    lblRegNumber.text = szReg;   
} 
</code>

Когда я запускаю свое приложение, я получаю следующие ошибки:

<code>2012-05-10 14:58:38.169 CCoDBTry[355:f803] Opened sqlite database at /Users/Matt****/Library/Application Support/iPhone Simulator/5.1/Applications/5DB7A218-A0F6-   485F-B366-91FD2F9BC062/Documents/tblStore.sqlite
2012-05-10 14:58:38.307 CCoDBTry[355:f803] sql problem occured with: SELECT strStore, strReg FROM tblStore WHERE strStore = 8053 AND strReg = 4;
2012-05-10 14:58:38.308 CCoDBTry[355:f803] no such column: strStore
</code>

Я ценю любого, кто тратит время, чтобы объяснить некоторые из этих вещей, так как я очень новичок и не смог выполнить некоторые из вещей, которые я пробовал. Большое спасибо за помощь!

Ваш Ответ

6   ответов
0

Вы можете открыть терминал и перейти к / Users / Matt **/ Библиотека / Поддержка приложений / iPhone Simulator / 5.1 / Приложения / 5DB7A218-A0F6-485F-B366-91FD2F9BC062 / Документы /

тогда sqlite3 tblStore.sqlite

затем используйте .schema. tblStore должен показать схему вашей таблицы, и вы увидите, правильно ли она была построена.

Ваша база данных должна находиться в каталоге документов для доступа для записи. Если ваша база данных будет только для чтения, то запись в нее никогда не может быть в вашем комплекте приложений. Один из способов сделать это - создать файл database.sqlite, добавить его в пакет и скопировать его в каталог документов (если он там еще не существует) при запуске.

2

Вы можете использовать следующий код, чтобы получить базу данных, созданную в папке Documents. Просто укажите путь в папке документов, и функция скопирует базу данных sqlite в папку «Документы» по указанному пути, если это необходимо. Затем вы можете использовать этот путь для создания и запроса таблиц базы данных.

+ (NSString*) createDatabaseIfRequiredAtPath:(NSString*)databasePath {

    if (databasePath == nil)
       return nil;


   NSString *path = [NSString stringWithFormat:@"%@/%@", databasePath, kMainDBName];
   NSFileManager *fileManager = [NSFileManager defaultManager];
   NSError *error = nil;

   if ([fileManager fileExistsAtPath:path] == NO) 
   {
    // The writable database does not exist, so copy the default to the appropriate location.
      NSString *defaultDBPath = [[NSBundle mainBundle] pathForResource:kMainDBName
                                                              ofType:nil];
      BOOL success = [fileManager copyItemAtPath:defaultDBPath 
                                       toPath:path
                                        error:&error];
      if (!success)
      {
        NSCAssert1(0, @"Failed to create writable database file with message '%@'.", [  error localizedDescription]);
        return nil;
    }
}

return path;
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Skizz
11

// Создать БД

-(NSString *) filePath
{
 NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *documentDirectory=[paths objectAtIndex:0];
 return [documentDirectory stringByAppendingPathComponent:@"LoginDatabase.sql"];
}

// Открываем БД

-(void)openDB
{
 if(sqlite3_open([[self filePath]UTF8String], &db) !=SQLITE_OK)
 {
   sqlite3_close(db);
   NSAssert(0, @"Database failed to Open");
 }
}

// Создать таблицу

-(void) createTableNamed:(NSString*)tableName withField1:(NSString*) field1 withField2:(NSString*) field2

{
   char *err;
   NSString *sql=[NSString stringWithFormat:@" CREATE TABLE IF NOT EXISTS '%@'('%@' TEXT PRIMARY KEY,'%@' TEXT);",tableName,field1,field2];

   if(sqlite3_exec(db, [sql UTF8String], NULL, NULL, &err) !=SQLITE_OK)
   {
    sqlite3_close(db);
    NSAssert(0, @"Table failed to create");
   }
}

// Вставка записей

-(void)insertrecordIntoTable:(NSString*) tableName withField1:(NSString*) field1 field1Value:(NSString*)field1Vaue andField2:(NSString*)field2 field2Value:(NSString*)field2Value
{

  NSString *sqlStr=[NSString stringWithFormat:@"INSERT INTO '%@'('%@','%@')VALUES(?,?)",tableName,field1,field2];
 const char *sql=[sqlStr UTF8String];

 sqlite3_stmt *statement1;

 if(sqlite3_prepare_v2(db, sql, -1, &statement1, nil)==SQLITE_OK)
 {
  sqlite3_bind_text(statement1, 1, [field1Vaue UTF8String], -1, nil);
  sqlite3_bind_text(statement1, 2, [field2Value UTF8String], -1, nil);
 }
 if(sqlite3_step(statement1) !=SQLITE_DONE)
    NSAssert(0, @"Error upadating table");
 sqlite3_finalize(statement1);
}

// Получить данные из таблицы

-(void)getAllRowsFromTableNamed:(NSString *)tableName
{
  NSString *field1Str,*field2Str;

  NSString *qsql=[NSString stringWithFormat:@"SELECT * FROM %@",tableName];
  sqlite3_stmt *statement;
  if(sqlite3_prepare_v2(db, [qsql UTF8String], -1, &statement, nil)==SQLITE_OK)
  {
   while(sqlite3_step(statement) ==SQLITE_ROW)
   {
     char *field1=(char *) sqlite3_column_text(statement, 0);
     char *field2=(char *) sqlite3_column_text(statement, 1);

     field1Str=[[NSString alloc]initWithUTF8String:field1];
     field2Str=[[NSString alloc] initWithUTF8String:field2];

     NSString *str=[NSString stringWithFormat:@"%@ - %@",field1Str,field2Str];
     NSLog(@"%@",str);
   }
}

}

В viewDidLoad вызовите методы

- (void)viewDidLoad
{

  [self openDB];
  [self createTableNamed:@"Login" withField1:@"USERNAME" withField2:@"PASSWORD"];
  [self insertrecordIntoTable:@"Login" withField1:@"USERNAME" field1Value:username andField2:@"PASSWORD" field2Value:password];

}

Где имя пользователя и пароль являются значениями NSString;

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededappcoda.com/sqlite-database-ios-app-tutorial
0

Есть ли конкретная причина, по которой вы хотели бы использовать SQLLite напрямую, а не CoreData? CoreData использует базу данных SQLLite, но сама является высокоуровневым API, и, в частности, с табличными представлениями и т. Д., Вы получаете множество функций и шаблонных методов, которые уже настроены для нее в XCode. Определение моделей данных тривиально, вы получаете тонны стандартного кода, и все это оптимизировано.

http://www.raywenderlich.com/934/core-data-on-ios-5-tutorial-getting-started

CoreData иногда описывается как крутая кривая обучения. Я не согласен. Если вы планируете самостоятельно писать SQL в своем приложении, у вас не возникнет никаких проблем с CoreData.

Термин «песочница» является абстрактным термином для части файловой системы устройства, к которой ваше приложение имеет доступ для чтения / записи. & Quot; Документы & quot; каталог - это конкретный каталог в изолированной программной среде вашего приложения. В вашей песочнице есть и другие файлы, кроме каталога документов, но большинство приложений, которые сохраняют данные в файловую систему iOS, делают это в каталоге документов.

Error: User Rate Limit Exceeded Skizz
0

может быть, вы забыли табличные вставки. Создана база данных и таблица, но ее пустая таблица.  Вы пытаетесь прочитать записи из таблицы, которая пуста.

Error: User Rate Limit Exceeded
2

sqlite - это боль, если вы не знаете, что делаете. У меня также были некоторые проблемы с функциями sqlite c, но затем я решил использовать упаковщик sqlite.

FMDB а такжеBWDB хороши и просты в использовании упаковщики sqlite для цели c. Я предлагаю вам использовать один из них.

Обратите внимание, что BWDB находится в учебнике lynda.com (этот) и если вы не можете найти его в Интернете ... оставьте комментарий, и я буду загружать его куда-нибудь.

редактировать: единственное место, где вы можете написать что-то в своем приложении, находится в вашем каталоге документов ... так что .. в чистом виде ... если БД не находится в вашем каталоге документов .. это только для чтения .. также .. когда вы читаете / записываете в свою базу данных .. ОС копирует базу данных в каталог документов .. и выполняет там все операции чтения и записи, так что вы можете иметь базу данных в своем комплекте приложений, но вы не можете ее редактировать ... так у вас получится 2 дБ. У меня была такая же проблема ... и я исправил ее, объединив 2 дБ, когда обновил приложение

edit2: я загрузил финальный проект BWDB (у вас есть оболочка и проект, чтобы увидеть, как он работает)

Error: User Rate Limit Exceeded Skizz
Error: User Rate Limit Exceeded

Похожие вопросы