2012-10-22 13 views
6

私は3つのクラスを持っています。 DBとテーブルをセットアップするには、うまく動作します。 DBHelper.javaSQLiteクエリSQLiteLog(1)そのような列:

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

次は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; 

     } 

私の第三のクラスを呼び出すと確認するために使用され、私の機能を持っています。しかし、これは私の問題が発生する場所か、前のクラスのfetchSiteIdByNameです。

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

私がアプリケーションを実行すると、私は新しい詳細を使ってDBに挿入します。 adbを使用するDBをプルし、sqlite3で開きます。最初の列にNULLを、最後にNULLを持つすべてのエントリを表示します(最後はまだ投稿されていません)。 私はeditbox siteDataのフィールドに同じテキストを使用し、新しいエントリを追加するだけで、以前のものは更新しません。

ログcatはSQLiteLog(1)を表示していません。xxxここで、xxxはautocompleteTextViewのエントリです。

入力されたテキストに名前が付けられた列を探しているのはなぜですか?

答えて

1

私は3つの異なる問題を抱えていたようですが、Lokeshのリンクと投稿の助けを借りて修正を得ています。

I))は、この

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

にDBelper.javaでSQL文字列を変更し、moveToFirst(後にセミコロンを削除DBControl.javaクラスに

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

を追加しました。私が言ったように、私は本当のノブですが、これが正しいと信じています。

AUTOINCREMENTを追加すると、アプリケーションをアンインストールして再インストールしたときに1つの劇的な効果がありました(DBバージョンを変更した可能性もあります)。

テーブルが再構築されたとき、前に見たカラム_idはありませんでした。だから私はSQL文字列が私の失敗の理由だと思う。私は、PRIMARY KEY basecolumns._IDのために必要ではないと聞いたと確信していますが、今はそれが分かります。

ありがとうございました。私は何の指針もなく問題を発見することができず、本当に感謝しています。

上向き矢印に追加しようとしましたが、まだ十分な評価がありません。 Doh。

他人に役立つことを願っています。

+0

このリンクも本当に助けになりました。 http://stackoverflow.com/questions/10573985/error-android-database-cursorindexoutofboundsexception-index-0-要求された – user1763585

2

fetchSiteIdByName()内のNAMEを一重引用符で囲むと役立ちます。

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

私はそれがSQLite上で動作するかどうかはよくわかりませんが、私はMySQLで同じ種類の問題を経験しています。さらに、データベースで数値以外の値をフェッチするときには、それらを一重引用符で囲みます。

希望します。 :)

+0

一重引用符、一重引用符、二重引用符を追加しようとしましたが、最後のクラスでキャッチしたエラーを返しました。 else {notice.setTitle( "Update failed!"); msgBody.setText( "サイトは既に存在しますが、失敗しました!"); それはそのような列」上記のようにlogcatで同じエラーで、重複したエントリでした: は、それからちょうど新しいエントリで出墜落 E/AndroidRuntime(3835):?android.database.CursorIndexOutOfBoundsException:インデックス0 0のサイズでリクエストされました – user1763585

+0

根本原因である別の場所で自分自身でエラーが発生しましたか? – user1763585

+0

結構です。これを確認してください。http://stackoverflow.com/questions/5316336/cursor-index -out-of-bounds-index-0-requested-with-size-0 –

関連する問題