2017-05-12 5 views
0

Innerhalb der Klasse DataBaseSqlite verwende ich DATABASE_CREATE_CLIENT Inside-Methode onCreate Datenbank zu erstellen.Spalte von SQLite nach dem Einfügen nicht gefunden

package DataBaseSqlite; 

import android.content.Context; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteOpenHelper; 
import android.util.Log; 

/** 
* Created by jur_1 on 02-Apr-17. 
*/ 

public class MySQLiteHelper extends SQLiteOpenHelper 
{ 
    //CLIENT VARIABLES 
    public static final String TABLE_CLIENT = "clients"; 
    public static final String CLIENT_ID = "rowid "; 
    public static final String CLIENT_NAME = "name"; 
    public static final String CLIENT_CONTACT_ID = "contactId"; 

    private static final String DATABASE_NAME = "JurBankTransactions.db"; 
    private static final int DATABASE_VERSION = 5; 


    //CLIENT TABLE 
    private static final String DATABASE_CREATE_CLIENT = "create table " + TABLE_CLIENT + "(" + CLIENT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " 
      + CLIENT_NAME + " text not null, " + CLIENT_CONTACT_ID + " text not null)"; 
    private static final String DATABASE_CREATE_TRANSACTIONS = "create table transactions(_id integer key auto increment, clientID integer, typeID integer, debt integer, quantity integer, date text)"; 
    private static final String DATABASE_CREATE_TYPE = "create table types(_id integer key auto increment, name text not null)"; 


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

    @Override 
    public void onCreate(SQLiteDatabase db) 
    { 
     db.execSQL(DATABASE_CREATE_CLIENT); 
     db.execSQL(DATABASE_CREATE_TRANSACTIONS); 
     db.execSQL(DATABASE_CREATE_TYPE); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    { 
     Log.w(MySQLiteHelper.class.getName(), 
       "Upgrading database from version " + oldVersion + " to " 
         + newVersion + ", which will destroy all old data"); 
     db.execSQL("DROP TABLE IF EXISTS clients"); 
     db.execSQL("DROP TABLE IF EXISTS transactions"); 
     db.execSQL("DROP TABLE IF EXISTS types"); 
     onCreate(db); 
    } 
} 

Danach innen MainActivity I Absicht nennen, die und Daten über den Kontakt Kontakte öffnen auswählt, den Benutzers retrive. Dann rufe ich Methode createClient, die innerhalb der Klasse CliendDataSource befindet, in dem cursorToClient heißt und ich kann contactId Wert nicht abrufen.

package CustomListView; 

/** 
* Created by jur_1 on 10-May-17. 
*/ 

import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.util.Log; 

import java.util.ArrayList; 
import java.util.List; 

import DataBaseSqlite.Client; 
import DataBaseSqlite.MySQLiteHelper; 

public class ClientDataSource 
{ 
    private SQLiteDatabase database; 
    private MySQLiteHelper dbHelper; 
    private String[] allColumns = {MySQLiteHelper.CLIENT_ID, MySQLiteHelper.CLIENT_NAME}; 

    public ClientDataSource(Context context) 
    { 
     dbHelper = new MySQLiteHelper(context); 
    } 

    public void open() throws SQLException 
    { 
     database = dbHelper.getWritableDatabase(); 
    } 

    public void close() 
    { 
     dbHelper.close(); 
    } 

    public Client createClient(String name, String contactId) 
    { 
     ContentValues values = new ContentValues(); 
     values.put(MySQLiteHelper.CLIENT_NAME, name); 
     values.put(MySQLiteHelper.CLIENT_CONTACT_ID, contactId); 
     Log.d("CREATE_CLIENT", "values contact id: " + contactId); 
     Log.d("CREATE_CLIENT", "values length: " + values.size()); 
     long insertId = database.insert(MySQLiteHelper.TABLE_CLIENT, null, 
       values); 
     System.out.println("new id: " + insertId); 
     Cursor cursor = database.query(MySQLiteHelper.TABLE_CLIENT, 
       allColumns, MySQLiteHelper.CLIENT_ID + " = " + insertId, null, 
       null, null, null); 
     cursor.moveToFirst(); 
     Client newClient = cursorToClient(cursor); 
     cursor.close(); 
     return newClient; 
    } 

    public void deleteClient(Client client) 
    { 
     long id = client.getId(); 
     System.out.println("Client deleted with id: " + id); 
     database.delete(MySQLiteHelper.TABLE_CLIENT, MySQLiteHelper.CLIENT_ID 
       + " = " + id, null); 
    } 

    public List<Client> getAllClients() 
    { 
     List<Client> clients = new ArrayList<Client>(); 

     Cursor cursor = database.query(MySQLiteHelper.TABLE_CLIENT, 
       allColumns, null, null, null, null, null); 

     cursor.moveToFirst(); 
     while (!cursor.isAfterLast()) 
     { 
      Client client = cursorToClient(cursor); 
       clients.add(client); 
       cursor.moveToNext(); 
     } 
     // make sure to close the cursor 
     cursor.close(); 
     return clients; 
    } 

    private Client cursorToClient(Cursor cursor) 
    { 
     Log.d("cursorToClient", "cursor num of columsn: " + cursor.getColumnCount()); 
     Client client = new Client(); 
     client.setId(cursor.getLong(0)); 
     Log.d("cursorToClient", "column id: " + cursor.getLong(0)); 
     client.setName(cursor.getString(1)); 
     Log.d("cursorToClient", "cursor name: " + cursor.getString(1)); 
     String[] columnNames = cursor.getColumnNames(); 
     for(String columnName : columnNames) 
     { 
      System.out.println("Column: " + columnName); 
     } 
     Log.d("cursorToClient", "column name 2: " + cursor.getColumnName(2)); 
     client.setContactsId(cursor.getString(2)); 
     return client; 
    } 
} 

Ausgabe von log ist:

19:32.067 8647-8647/com.jurbank.jurbank.jurbank D/cursorToClient: cursor num of columsn: 2 
05-12 22:19:32.068 8647-8647/com.jurbank.jurbank.jurbank D/cursorToClient: column id: 1 
05-12 22:19:32.068 8647-8647/com.jurbank.jurbank.jurbank D/cursorToClient: cursor name: Alen Ban 
05-12 22:19:32.068 8647-8647/com.jurbank.jurbank.jurbank I/System.out: Column: rowid 
05-12 22:19:32.068 8647-8647/com.jurbank.jurbank.jurbank I/System.out: Column: name 

Fehler:

05-12 22:19:32.069 8647-8647/com.jurbank.jurbank.jurbank E/AndroidRuntime: FATAL EXCEPTION: main 
                      Process: com.jurbank.jurbank.jurbank, PID: 8647 
                      java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { dat=content://com.android.contacts/contacts/lookup/549i30872f420c7a3b2e.1115i91.1419r1625-293F31432B2943/95 flg=0x1 }} to activity {com.jurbank.jurbank.jurbank/com.jurbank.jurbank.jurbank.MainActivityClients}: java.lang.ArrayIndexOutOfBoundsException: length=2; index=2 
                       at android.app.ActivityThread.deliverResults(ActivityThread.java:3699) 
+0

Was sind die Protokolle ausgegeben? – FAT

+0

Löschen Sie die Datenbank (z. B. Einstellungen/Apps löschen Daten) oder ändern Sie die Versionsnummer, nachdem Sie Änderungen vorgenommen haben? Die onCreate-Methode wird nur aufgerufen, wenn die Datenbank nicht existiert (oder Sie sie explizit aufrufen). Wenn Sie die Versionsnummer ändern, werden die Tabellen gelöscht und "onCreate" aufgerufen. P.S. Sie möchten wahrscheinlich nicht AUTOINCREMENT (gemäß _he AUTOINCREMENT Schlüsselwort auferlegt zusätzliche CPU, Arbeitsspeicher, Speicherplatz und Festplatten-I/O Overhead und sollte vermieden werden, wenn nicht unbedingt erforderlich. Es ist in der Regel nicht erforderlich. siehe https: // sqlite. org/autoinc.html) – MikeT

+0

@MikeT Wenn ich Änderungen an der Datenbank mache, lösche ich einfach die App und installiere sie erneut, aber ich habe auch versucht, die Versionsnummer der Datenbank zu erhöhen. Was sollte ich anstelle von AUTOINCREMENT für rowid verwenden, damit jede neue Zeile eine neue Rowid hat? – Jure

Antwort

1

Ich denke, das Problem in Ihrer Aussage ist DATABASE_CREATE_CLIENT. Möglicherweise wird die Spalte CLIENT_CONTACT_ID aufgrund fehlender space vor Ende ")" nicht hinzugefügt.

Aktualisieren Sie Ihre Tabelle erstellen statement wie folgt:

//CLIENT TABLE 
private static final String DATABASE_CREATE_CLIENT = "CREATE TABLE " + TABLE_CLIENT + "(" + CLIENT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " 
     + CLIENT_NAME + " TEXT NOT NULL, " + CLIENT_CONTACT_ID + " TEXT NOT NULL)"; 

Auch CLIENT_ID Raum aus Spaltennamen entfernen.

Verwendung:

public static final String CLIENT_ID = "rowid"; 

Statt:

public static final String CLIENT_ID = "rowid "; 

Schließlich uninstall & install wieder Ihre Anwendung.

Hope this helfen ~

+0

Ich habe ganze Methode hinzugefügt, wo ich INSERT verwende. – Jure

+0

Stellen Sie sicher, dass die contactId nicht null – FAT

+0

Wenn ich es im Protokoll ausgibt, ist es nicht null. – Jure

1

Nicht, dass ich bin sicher, dass das Problem aber Folgenden basierend auf Ihren Code arbeitet. Ich hatte ein Problem (wie Kommentar in Ferdous Post) mit "Rowid" mit dem Platz. Dies wurde jedoch unter Verwendung der Variablen, die an getColumnIndex() übergeben wurde, d. H. Mit dem Abstand, den sie zurückgab, -1 (nicht gefunden).

hier ist jedenfalls einige Code, der für mich arbeitet, die sehr viel von Ihrem Code (abzüglich der Client-Klasse Zeug) basiert: -

Die DBHelper (mit addClient und getAllClients für testiing): -

public class DBHelperClients extends SQLiteOpenHelper { 

    //CLIENT VARIABLES 
    public static final String TABLE_CLIENT = "clients"; 
    public static final String CLIENT_ID = "rowid"; 
    public static final String CLIENT_NAME = "name"; 
    public static final String CLIENT_CONTACT_ID = "contactId"; 

    private static final String DATABASE_NAME = "JurBankTransactions.db"; 
    private static final int DATABASE_VERSION = 5; 


    //CLIENT TABLE 
    private static final String DATABASE_CREATE_CLIENT = "create table " + TABLE_CLIENT + 
      "(" + CLIENT_ID + " INTEGER PRIMARY KEY, " 
      + CLIENT_NAME + " text not null, " 
      + CLIENT_CONTACT_ID + " text not null)"; 

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

    } 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL(DATABASE_CREATE_CLIENT); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) { 

    } 

    public long addClient(String name, String contact) { 
     SQLiteDatabase db = this.getWritableDatabase(); 
     ContentValues cv = new ContentValues(); 
     cv.put(CLIENT_NAME,name); 
     cv.put(CLIENT_CONTACT_ID,contact); 
     return db.insert(TABLE_CLIENT,null,cv); 
    } 

    public Cursor getAllClients() { 
     SQLiteDatabase db = this.getReadableDatabase(); 
     return db.query(TABLE_CLIENT,null,null,null,null,null,null); 
    } 
} 

Die rufenden Aktivität ist wie folgt: -

public class MainActivity extends AppCompatActivity { 
    //DBHelper db; 
    DBHelperClients db; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     db = new DBHelperClients(this); 
     db.addClient("Fred","email"); 
     db.addClient("Bert","snailmail"); 
     db.addClient("Harry","smoke signals"); 

     Cursor myclients = db.getAllClients(); 
     while (myclients.moveToNext()) { 
      Log.d("MYCLIENT","Client name=" + 
        myclients.getString(myclients.getColumnIndex(DBHelperClients.CLIENT_NAME)) + 
        "\tClient Contact=" + 
        myclients.getString(myclients.getColumnIndex(DBHelperClients.CLIENT_CONTACT_ID)) + 
        "\tID=" + Long.toString(myclients.getLong(myclients.getColumnIndex(DBHelperClients.CLIENT_ID))) 
      ); 
     } 
    } 
} 

Das Protokoll (nach dem 2. Lauf, so dass die Daten duplizieren): -

05-13 18:49:16.058 7260-7260/mjt.testvcsuse D/MYCLIENT: Client name=Fred Client Contact=email ID=1 
05-13 18:49:16.058 7260-7260/mjt.testvcsuse D/MYCLIENT: Client name=Bert Client Contact=snailmail ID=2 
05-13 18:49:16.058 7260-7260/mjt.testvcsuse D/MYCLIENT: Client name=Harry Client Contact=smoke signals ID=3 
05-13 18:49:16.058 7260-7260/mjt.testvcsuse D/MYCLIENT: Client name=Fred Client Contact=email ID=4 
05-13 18:49:16.058 7260-7260/mjt.testvcsuse D/MYCLIENT: Client name=Bert Client Contact=snailmail ID=5 
05-13 18:49:16.058 7260-7260/mjt.testvcsuse D/MYCLIENT: Client name=Harry Client Contact=smoke signals ID=6 

Feine Unterschiede, die kein Problem behoben haben sollten, sind

I while(cursor.moveToNext()) {} eine Schleife durch den Cursor verwendet hat und stattdessen spezifische Offsets für Spalten verwenden, wenn Daten aus dem Cursor zu bekommen. Ich habe cursor.getColumnIndex(name of the column) verwendet, die flexibler ist.

Vielleicht versuchen Sie mit dem oben genannten, sehen, ob es funktioniert und dann passen Sie es für Ihre Bedürfnisse.

+0

Wenn das oben genannte nicht hilfreich ist, dann bearbeiten Sie vielleicht den ursprünglichen Post, um die Client-Klasse aufzunehmen. – MikeT

+0

Ich habe meinen Fehler gefunden. Ich weiß nicht, ob ich Ihre oder @ Ferdous Antwort akzeptieren oder meine eigene hinzufügen sollte. Problem war in dieser Zeile: private Zeichenfolge [] allColumns = {MySQLiteHelper.CLIENT_ID, MySQLiteHelper.CLIENT_NAME}; Dies wird in der Abfrage verwendet und sollte alle Spalten in der Zeile zurückgeben, aber wenn ich contact_id zur Tabelle hinzugefügt habe, habe ich es hier nicht hinzugefügt. Also gab die Abfrage immer nur zwei Zeilen zurück. – Jure

+0

@Jure OMG, sehr interessantes Thema 'allColumns'. Ich habe viel von Ihrer Frage gelernt :) – FAT

Verwandte Themen