Невозможно создать вторую таблицу в sqlite - PullRequest
0 голосов
/ 17 ноября 2011

Перепробовав все возможные решения из блогов, форумов, веб-страниц, я задал этот вопрос.

Изначально я создал базу данных с таблицей «registrationTable» и смог выполнить все операции CRUD. Затем я попытался добавить вторую таблицу «targetTable», которая по какой-то причине не создается.

Я пытался сделать следующие вещи:

изменил версию базы данных

изменил оператор создания для второй таблицы

включено "PRAGMA foreign_keys = ON;" так как вторая таблица содержит внешний ключ

поменял местами тип данных поля "cdate" с текста на дату и наоборот

но стол все еще не создан.

Код моего класса DBAdapter следующий:

 //Table 1
private static final String TAG = "DBAdapter";
private static final String DATABASE_TABLE = "registrationTable";
private static final String DATABASE_NAME = "project1database";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE = 
    "create table registrationTable ( phone integer primary key not null, name text not null, " +
    "age integer not null, area text not null, sex text not null);";

//Table 2
private static final String PURPOSE_TABLE = "purposeTable";
private static final String PURPOSE_CREATE = "create table purposeTable ( phone integer not null, foreign key (phone) references registrationTable(phone), " +
        "cdate text not null, primary key (phone, date), text1 text not null, text2 text not null);";

private final Context context;
private SQLiteDatabase db;
private DatabaseHelper DBHelper;

public DBAdapter(Context ctx){
    context = ctx;
}
//public DBAdapter read()throws SQLException
//public DBAdapter write()throws SQLException
//public void close()
//public long insertDetails(String name, int age, String area, int phone, String sex)

public long insertPurpose(String date, String text1, String text2){
    ContentValues initialValues1 = new ContentValues();
    initialValues1.put(CDATE, date);
    initialValues1.put(TEXT1, text1);
    initialValues1.put(TEXT2, text2);
    return db.insert(PURPOSE_TABLE, null, initialValues1);
}

private static class DatabaseHelper extends SQLiteOpenHelper{

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        try{
            db.execSQL(DATABASE_CREATE);
            db.execSQL(PURPOSE_CREATE);
            db.execSQL("PRAGMA foreign_keys = ON;");
        }catch(SQLException e){
            e.printStackTrace();
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading from version " + oldVersion + " to " + newVersion + ". All data will be deleted.");
        db.execSQL("DROP TABLE IF EXISTS registrationTable");
        db.execSQL("DROP TABLE IF EXISTS purposeTable");
        onCreate(db);
    }
}

И я вызываю метод insertPurpose () из другого класса с кодом ниже:

dbAdapter2.write();
dbAdapter2.insertPurpose(cDate, text1, text2);
dbAdapter2.close();

И журнал logcat выглядит так:

11-17 01:29:17.023: I/SqliteDatabaseCpp(15095): sqlite returned: error code = 1, msg = no such table: purposeTable, db=/data/data/com.android.project1/databases/project1database
11-17 01:29:17.143: E/SQLiteDatabase(15095): Error inserting text1=a text2=b cdate=17-11-2011 
11-17 01:29:17.143: E/SQLiteDatabase(15095): android.database.sqlite.SQLiteException: no such table: purposeTable: , while compiling: INSERT INTO purposeTable(text1,text2,cdate) VALUES (?,?,?)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.database.sqlite.SQLiteProgram.compileSql(SQLiteProgram.java:143)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.database.sqlite.SQLiteProgram.compileAndbindAllArgs(SQLiteProgram.java:361)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.database.sqlite.SQLiteStatement.acquireAndLock(SQLiteStatement.java:260)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:112)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1745)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1618)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at com.android.project1.DBAdapter.insertPurpose(DBAdapter.java:113)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at com.android.project1.Purpose3Activity$1.onClick(Purpose3Activity.java:51)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.view.View.performClick(View.java:3460)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.view.View$PerformClick.run(View.java:13955)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.os.Handler.handleCallback(Handler.java:605)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.os.Handler.dispatchMessage(Handler.java:92)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.os.Looper.loop(Looper.java:137)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at android.app.ActivityThread.main(ActivityThread.java:4340)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at java.lang.reflect.Method.invokeNative(Native Method)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at java.lang.reflect.Method.invoke(Method.java:511)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
11-17 01:29:17.143: E/SQLiteDatabase(15095):    at dalvik.system.NativeStart.main(Native Method)

Заранее спасибо, если кто-нибудь подскажет, где я ошибаюсь.

Вторая таблица создана, но данные не вставлены, новый журнал:

11-17 11:42:11.281: E/SQLiteDatabase(10172): Error inserting text1=e text2=d cdate=17-11-2011
11-17 11:42:11.281: E/SQLiteDatabase(10172): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at android.database.sqlite.SQLiteStatement.native_executeInsert(Native Method)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:113)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1745)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1618)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at com.android.project1.DBAdapter.insertPurpose(DBAdapter.java:113)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at com.android.project1.Purpose3Activity$1.onClick(Purpose3Activity.java:51)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at android.view.View.performClick(View.java:3460)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at android.view.View$PerformClick.run(View.java:13955)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at android.os.Handler.handleCallback(Handler.java:605)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at android.os.Handler.dispatchMessage(Handler.java:92)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at android.os.Looper.loop(Looper.java:137)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at android.app.ActivityThread.main(ActivityThread.java:4340)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at java.lang.reflect.Method.invokeNative(Native Method)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at java.lang.reflect.Method.invoke(Method.java:511)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
11-17 11:42:11.281: E/SQLiteDatabase(10172):    at dalvik.system.NativeStart.main(Native Method)

Ответы [ 4 ]

1 голос
/ 17 ноября 2011

В create table для второй таблицы вы пытаетесь создать первичный ключ поверх (телефон, дата). Там нет колонки date - только cdate. Кроме того, ограничения (т.е. первичный / внешний ключ) должны быть после объявлений полей. Будет работать следующий синтаксис:

create table purposeTable (
phone integer not null, 
cdate text not null,  
text1 text not null,
text2 text not null,

primary key (phone, cdate),
foreign key (phone) references registrationTable(phone));  

Прежде чем запускать какой-либо SQL на устройстве из программы, попробуйте запустить его в интерактивном режиме в базе данных SQLite на рабочем столе, посмотрите, как он работает. Гораздо проще отлаживать таким образом. Я рекомендую получить хороший настольный графический интерфейс SQLite, e. г. SQLiteStudio .

РЕДАКТИРОВАТЬ: ошибка вставки:

Вы не поставляете phone. Это ненулевое поле, оно должно быть предоставлено в операторе вставки, иначе ограничение not null не будет выполнено. Вот что говорит ошибка.

1 голос
/ 17 ноября 2011

Ваши ограничения таблицы должны прийти после определения столбца :

create table syntax diagram

Обратите внимание на "column-def" и "table-constraint"циклы в приведенной выше синтаксической диаграмме.

У вас также есть опечатка (date должно быть cdate) в вашем первичном ключе.

SQL для создания purposeTable должен выглядеть следующим образом:

create table purposeTable ( 
    phone integer not null,
    cdate text not null, 
    text1 text not null, 
    text2 text not null,   
    primary key (phone, cdate),
    foreign key (phone) references registrationTable(phone) 
);

Что касается вашего insertPurpose метода, он не будет работать, потому что вы phone помечены как not null в purposeTable, но insertPurpose не обеспечиваетценность для этого.У вас также есть phone как часть первичного ключа таблицы, поэтому вы не можете удалить not null.Я думаю, вы должны указать значение phone в insertPurpose.

0 голосов
/ 17 ноября 2011

Я чувствую, что в предложении есть какая-то ошибка, которая создает таблицу целей.Попробуйте выполнить его в оболочке, чтобы увидеть, работает ли он.

Когда у вас несколько таблиц в одной базе данных, мои личные рекомендации - использовать разные классы для разных таблиц и использовать предложение:

CREATETABLE ЕСЛИ НЕ СУЩЕСТВУЕТ tableName

вместо CREATE TABLE tableName

и переопределить метод onOpen объекта DataBaseHelper.

Это сделает ваш код намного более понятным и простым для отладки.

http://www.jiahaoliuliu.com/2011/09/sqlite-create-multiple-tables-with.html

0 голосов
/ 17 ноября 2011

Попробуйте установить DATABASE_VERSION = 2 для запуска onUpgrade, и ваша таблица будет создана.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...