SQLite-запрос SQLiteLog (1) нет такой колонки:

У меня 3 класса. Один для настройки БД и таблиц работает отлично. DBHelper.java

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

Теперь, когда я запускаю приложение, я вставляю его в БД с новыми деталями absolutley fine. Используя adb, я вытаскиваю DB и открываю в sqlite3. Он показывает все записи с NULL в первом столбце и NULL в последнем (последнее еще не опубликовано). Я использую тот же текст в поле editbox siteData, и он просто добавляет новую запись и не обновляет предыдущую.

Лог-кошка показывает SQLiteLog (1) нет такого столбца: xxx, где xxx было бы входом в autocompleteTextView.

Почему он ищет столбец с именем любого текста?

Возможно, вам поможет окружение NAME в fetchSiteIdByName () с одинарными кавычками.

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

Я не очень уверен, что он будет работать на SQLite, но у меня были такие же проблемы в MySQL, и это помогает. Более того, когда вы извлекаете нечисловые значения в базе данных, вы окружаете их в одинарных кавычках.

Надеюсь, поможет. 🙂

Похоже, у меня было 3 разных вопроса, но с помощью ссылок Lokesh и сообщений мне удалось исправить ситуацию.

Я изменил строку SQL в DBelper.java для этого

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

И добавлен в класс DBControl.java

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

Удаление точки с запятой после moveToFirst ()). Как я уже сказал, я настоящий нуб, но считаю, что это правильно.

Добавление AUTOINCREMENT имело 1 драматический эффект, когда я удалил и переустановил приложение (вместо этого я мог бы изменить версию БД, если я тоже захочу).

Когда таблицы были перестроены, у них не было столбца, который я видел раньше. Поэтому я считаю, что причиной отказа явилась строка SQL. Я уверен, что я слышал, где-то это не требовалось для PRIMARY KEY basecolumns._ID, но теперь я знаю, что это.

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

Я попытался добавить стрелку вверх, но пока не получил достаточной оценки. Doh.

Надеюсь, это поможет другим.