2012-10-22 10 views
6

Mam 3 klasy. Jeden do konfiguracji DB i tabel, działa dobrze. DBHelper.javaZapytanie SQLite SQLiteLog (1) brak takiej kolumny:

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); 
} 

Kolejnym z nich ma swoje funkcje 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; 

     } 

Trzecia klasa jest używana, aby zadzwonić i sprawdzić. Ale tutaj pojawia się mój problem lub w fetchSiteIdByName w poprzedniej klasie.

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(); 
    } 
    } 
    } 

Teraz po uruchomieniu aplikacji wstawiam do DB nowe szczegóły absolutnie w porządku. Używanie adb Wyciągam DB i otwiera w sqlite3. Pokazuje wszystkie wpisy z NULL w pierwszej kolumnie i NULL w ostatnim (ostatni nie został jeszcze wysłany). Używam tego samego tekstu w polu editbox siteData i po prostu dodaje nowy wpis i nie aktualizuje poprzedniego.

Log cat wyświetla SQLiteLog (1) brak takiej kolumny: xxx gdzie xxx byłby wejściem do autocompleteTextView.

Dlaczego szuka kolumny, której treść została wprowadzona?

Odpowiedz

1

Wygląda na to, że miałem 3 różne problemy, ale używając linków Lokesha i postów pomóż mi rozwiązać problem.

zmodyfikowałem ciąg SQL w DBelper.java do tego

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); 

i dodawane do klasy DBControl.java

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

spadnie średnik po moveToFirst()). Tak jak powiedziałem, jestem prawdziwym noobem, ale uważam, że jest to poprawne.

Dodanie AUTOINCREMENT miało 1 dramatyczny efekt po odinstalowaniu i ponownym zainstalowaniu aplikacji (zamiast tego mogłem zmienić wersję DB, jeśli chciałem też, wiem).

Po odbudowaniu Stołów nie mieli oni kolumny, którą widziałem wcześniej. Myślę więc, że ciąg SQL był przyczyną mojej awarii. Jestem pewien, że słyszałem gdzieś, że nie było to wymagane dla PRIMARY KEY basecolumns._ID, ale teraz wiem, że to JEST.

Dzięki Lokesh za Twoje wskazówki. Nie mogłem znaleźć problemu bez wskazówek i naprawdę to doceniam.

Próbowałem dodać do strzałki w górę, ale jeszcze nie mam wystarczającej oceny. Doh.

Mam nadzieję, że to pomoże innym.

+0

Ten link również pomógł. http://stackoverflow.com/questions/10573985/error-android-database-cursorindexboundexception-index-- proszony o pomoc – user1763585

2

Pomocne może być otaczanie NAZWA w parametrze fetchSiteIdByName() pojedynczym cudzysłowem.

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

Nie jestem pewien, czy to zadziała na SQLite, ale przeżyłem ten sam rodzaj problemów w MySQL i pomaga. Co więcej, podczas pobierania wartości nieliczbowych w bazie danych otaczasz je pojedynczymi cudzysłowami.

Mam nadzieję, że to pomaga. :)

+0

Próbowałem dodać pojedynczy i podwójny cudzysłów, pojedynczy cudzysłów, podwójny cudzysłów, ale zwrócił błąd złapany w ostatniej klasie else {notice.setTitle ("Aktualizacja nie powiodła się!"); msgBody.setText ("Strona już istnieje, ale się nie udało!"); gdy był duplikatem wejścia, z tego samego błędu w LogCat jak wyżej „Taki kolumny: Wtedy właśnie rozbił się z nowego wpisu E/Android Runtime (3835): android.database.CursorIndexOutOfBoundsException: Index 0 wymagane, o rozmiarze 0 – user1763585

+0

Czy mam błąd w innym miejscu, który jest przyczyną główną? – user1763585

+0

Tak, i myślę, że powinieneś to sprawdzić, ponieważ może to pomóc http://stackoverflow.com/questions/5316336/cursor-index -out-of-bounds-index-0-requested-with-size-0 –

Powiązane problemy