2012-10-22 8 views
6

Ho 3 classi. Uno per impostare il DB e le tabelle, funziona correttamente. DBHelper.javaSQLite query SQLiteLog (1) nessuna colonna:

private static final String TAG = "DBHelper"; 
public static final String DB_NAME = "pat_test.db"; 
public static final String TABLE5 = "sites"; 
public static final String S_ID = BaseColumns._ID; 
public static final String S_CLIENT = "client_of_site"; 
public static final String S_POSTCODE = "site_postode"; 
public static final String S_CON_NAME = "contact_name"; 
public static final String S_CON_NUM = "contact_tel_num"; 
public static final String S_NAME = "site_name"; 
public static final String S_LAST_TEST = "last_test_date"; 

public DBHelper(Context context) { 
    super(context, DB_NAME, null, DB_VERSION); 

} 

@Override 
public void onCreate(SQLiteDatabase db) { 


String sql5 = String.format("create table %s (%s INT PRIMARY KEY, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s INT, %s TEXT)",TABLE5, S_ID, S_CLIENT, S_NAME, S_POSTCODE, S_CON_NAME,S_CON_NUM,S_LAST_TEST); 
Log.d(TAG, "onCreate: " + sql5); 
db.execSQL(sql5); 
} 

Il prossimo ha le mie funzioni DBControl.java

import android.content.ContentValues; 
import android.content.Context; 
import android.database.Cursor;  
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 
import android.provider.BaseColumns; 

public class DBControl { 

public static final String TABLE5 = "sites"; 

public static final String S_ID = BaseColumns._ID; 
public static final String S_CLIENT = "client_of_site"; 
public static final String S_NAME = "site_name"; 
public static final String S_POSTCODE = "site_postode"; 
public static final String S_CON_NAME = "contact_name"; 
public static final String S_CON_NUM = "contact_tel_num"; 
public static final String S_LAST_TEST = "last_test_date"; 

private Context context; 
private SQLiteDatabase database; 
private DBHelper dbhelper; 

public DBControl(Context context) { 

    this.context = context; 

} 

    public DBControl open() throws SQLiteException { 

    dbhelper = new DBHelper(context); 
    database = dbhelper.getWritableDatabase(); 
    return this; 
} 

public void close() { 

    dbhelper.close(); 

} 
    public ContentValues createContentValues3(String CLIENT, 
     String NAME, String POSTCODE, String CON_NAME, 
     long CON_NUM) { 

    ContentValues values = new ContentValues(); 
    values.put(S_CLIENT, CLIENT); 
    values.put(S_POSTCODE, POSTCODE); 
    values.put(S_CON_NAME, CON_NAME); 
    values.put(S_CON_NUM, CON_NUM); 
    values.put(S_NAME, NAME); 
    return values; 
    } 
    public long addSiteDetails(String CLIENT, String NAME, 
     String POSTCODE, String CON_NAME, int CON_NUM) { 

    ContentValues siteValues = createContentValues3(CLIENT, NAME, 
      POSTCODE, CON_NAME, CON_NUM); 

    return database.insert(TABLE5, null, siteValues); 
} 


public boolean updateSiteDetails(long id, String CLIENT, String NAME, 
     String POSTCODE, String CON_NAME , int CON_NUM 
     ) { 

    ContentValues siteUpdateValues = createContentValues3(CLIENT, NAME, 
      POSTCODE, CON_NAME, CON_NUM); 

    return database.update(TABLE5, siteUpdateValues, S_ID + "=" + id, null) > 0; 
} 

} 
    public long fetchSiteIdByName(String NAME){ 

    Cursor dbCursor; 
    long id = 0; 

     try { 

    dbCursor = database.query(true, TABLE5, new String []{S_ID}, S_NAME + "= " + NAME , null, null, null, null, null); 
    dbCursor.moveToFirst(); 
    id = dbCursor.getLong(dbCursor.getColumnIndex(S_ID)); } 

     catch (SQLiteException e) { 

      id = -1; 

     } 

     return id; 

     } 

mia terza classe viene utilizzata per chiamare e verificare. Ma questo è dove sorge il mio problema o in fetchSiteIdByName nella classe precedente.

import android.app.Activity; 
    import android.app.Dialog; 
    import android.content.Intent; 
    import android.database.sqlite.SQLiteException; 
    import android.os.Bundle; 
    import android.view.Menu; 
    import android.view.View; 
    import android.view.View.OnClickListener; 
    import android.widget.AutoCompleteTextView; 
    import android.widget.Button; 
    import android.widget.EditText; 
    import android.widget.TextView; 
    import android.widget.Toast; 

    public class activityStartNewTest extends Activity implements OnClickListener { 

Button buttonBeginTesting; 
private AutoCompleteTextView clientInput;  //Refers to input box for client 
private AutoCompleteTextView siteInput;   //Refers to input box for site 
private AutoCompleteTextView postcodeInput;  //Refers to input box for postcode 
private EditText nameInput;      //Refers to input box for contact name 
private EditText telInput;      //Refers to input box for contact number 
    // private EditText jobrefInput;     //Refers to input box for Job reference number 

private DBControl dbControl;     

@ Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.start_new_test); 
    dbControl = new DBControl(this); 
    clientInput = (AutoCompleteTextView) findViewById(R.id.autoCompleteClientNameEdit); 
    siteInput = (AutoCompleteTextView) findViewById(R.id.autoCompleteSiteNameEdit); 
    postcodeInput = (AutoCompleteTextView) findViewById(R.id.autoCompletePostcodeEdit); 
    nameInput = (EditText) findViewById(R.id.editTextContactName); 
    telInput = (EditText) findViewById(R.id.editTextContactNum); 
    //  jobrefInput = (EditText)findViewById(R.id.editTextJobRef);  

    buttonBeginTesting = (Button) findViewById(R.id.buttonBeginTesting); 
    buttonBeginTesting.setOnClickListener(this); 
} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 


public void onClick(View arg) { 

    String clientData = clientInput.getText().toString(); 
    String siteData = siteInput.getText().toString(); 
    String postcodeData = postcodeInput.getText().toString(); 
    String nameData = nameInput.getText().toString(); 
    String telData = telInput.getText().toString(); 
    // String jobrefData = jobrefInput.getText().toString(); 

    Toast toastNotice = new Toast(this); 
    Dialog notice = new Dialog(this); // this needs the textview below for displaying 
    TextView msgBody = new TextView(this); 
    msgBody.setTextSize(20); 
    long tempValue = 0; 

    switch(arg.getId()){ 

    case R.id.buttonBeginTesting: 

    try{ 
     int telDataAsNum = Integer.parseInt(telData); 
     dbControl.open(); 

     if((tempValue = dbControl.fetchSiteIdByName(siteData)) != -1) { 

      if(dbControl.updateSiteDetails(tempValue, clientData, siteData, postcodeData, nameData, telDataAsNum)){ 
       notice.setTitle("Site Updated!"); 
       msgBody.setText("Site detail have been updated instead"); 
      } 
      else{ 
       notice.setTitle("Update failed!"); 
       msgBody.setText("Site already Exists, but failed!"); 
      } 
     } 
     else{ 
      long siteID = 0; 

      siteID = dbControl.addSiteDetails(clientData, siteData, postcodeData, nameData, telDataAsNum); 
      notice.setTitle("Site Added"); 
      msgBody.setText("Site added at row "+ siteID); 
    } 
    dbControl.close(); 

    } 
    catch (SQLiteException e){ // Notifies user if SQL error occurred 
     e.printStackTrace(); 
     notice.setTitle("Insert failed"); 
     msgBody.setText("SQL Error!"); 
    } 
    catch (NumberFormatException e){ // Notifies user if NUM format error occurred 
     e.printStackTrace(); 
     notice.setTitle("Insert failed"); 
     msgBody.setText("Contact number must be a number!"); 
    } 
    notice.setContentView(msgBody); 
    notice.show(); 
    } 
    } 
    } 

Ora quando eseguo l'applicazione inserisco nel DB con nuovi dettagli assolutamente bene. Utilizzo di adb Tiro il DB e apro in sqlite3. Mostra tutte le voci con NULL nella prima colonna e NULL nell'ultima (l'ultima non è stata ancora pubblicata). Io uso lo stesso testo nel campo editbox siteData e aggiunge solo una nuova voce e non aggiorna il precedente.

Il log cat mostra SQLiteLog (1) nessuna colonna: xxx dove xxx sarebbe stata la voce in autocompleteTextView.

Perché è in cerca di una colonna denominata per qualsiasi testo è stato inserito?

risposta

1

Sembra che ho avuto 3 diversi problemi ma usando i collegamenti di Lokesh e il post mi aiutano a ottenere una soluzione.

ho modificato la stringa SQL in DBelper.java a questo

String sql5 = String.format("create table %s (%s INTEGER PRIMARY KEY **AUTOINCREMENT**, %s TEXT, %s TEXT, %s TEXT, %s TEXT, %s INT, %s TEXT)", 
        TABLE5, S_ID, S_CLIENT, S_NAME, S_POSTCODE, S_CON_NAME, 
        S_CON_NUM, S_LAST_TEST); 

e ha aggiunto alla classe DBControl.java

**if**(dbCursor.moveToFirst()) id = dbCursor.getLong(dbCursor.getColumnIndex(S_ID)); 

Lasciando cadere il punto e virgola dopo la moveToFirst()). Come ho detto, sono un vero noob ma credo che sia corretto.

L'aggiunta di AUTOINCREMENT ha avuto 1 effetto drammatico quando ho disinstallato e reinstallato l'applicazione (avrei potuto cambiare la versione DB, se volevo, lo so).

Quando le tabelle sono state ricostruite, non avevano la colonna _id che avevo visto prima. Quindi penso che la stringa SQL sia stata la ragione del mio fallimento. Sono sicuro di aver sentito da qualche parte che non era necessario per PRIMARY KEY basecolumns._ID ma ora so che è.

Grazie Lokesh per i tuoi suggerimenti. Non avrei potuto trovare il problema senza una guida e lo apprezzo davvero.

Ho provato ad aggiungere alla freccia su ma non ho ancora abbastanza voto. Doh.

Spero che questo aiuti gli altri.

+0

Anche questo link ha aiutato molto. http://stackoverflow.com/questions/10573985/error-android-database-cursorindexoutofboundsexception-index-0- richiesta-wit – user1763585

2

Circondare il NOME in fetchSiteIdByName() con virgolette singole può aiutare.

dbCursor = database.query(true, TABLE5, new String []{S_ID}, S_NAME + "= '" + NAME + "'" , null, null, null, null, null); 

io non sono molto sicuro se funzionerà su SQLite, ma ho passato lo stesso tipo di problemi in MySQL e aiuta. Inoltre, quando recuperi valori non numerici nel database li racchiudi tra virgolette singole.

Spero che aiuti. :)

+0

Ho provato ad aggiungere la virgoletta singola e doppia, virgoletta singola, virgoletta doppia ma ha restituito l'errore rilevato nell'ultima classe else {notice.setTitle ("Aggiornamento fallito!"); msgBody.setText ("Il sito esiste già, ma non è riuscito!"); quando era una voce duplicata, con lo stesso errore nel logcat come sopra "tale colonna:? Poi basta schiantato fuori con una nuova voce E/AndroidRuntime (3835): android.database.CursorIndexOutOfBoundsException: Indice 0 richiesto, con una dimensione pari a 0 – user1763585

+0

Ho ricevuto un errore altrove che è la causa principale? – user1763585

+0

Sì, e penso che dovresti controllare come potrebbe aiutare http://stackoverflow.com/questions/5316336/cursor-index -out-of-bounds-index-0-required-with-size-0 –