2015-04-09 2 views
0

Я хочу создать базу данных с тремя столбцами (название точки интереса, долготы и широты). Поскольку я совершенно новичок в базах данных, я использую пример, который я нашел в Интернете, и попытаюсь изменить его на мой случай. Проблема в том, что она работает для 1 колонки, но если я добавлю другую, то она сломается. Это мой код:Android Studio - создать базу данных с несколькими столбцами

TaskContract

import android.provider.BaseColumns; 

public class TaskContract { 
    public static final String DB_NAME = "com.example.TodoList.db.tasks"; 
    public static final int DB_VERSION = 1; 
    public static final String POI_NAMES = "tasks"; 
    public static final String LONGITUDES = "longs"; 
    public static final String LATITUDES = "lats"; 


    public class Columns { 
     public static final String POI = "task"; 
     public static final String _ID = BaseColumns._ID; 
     public static final String LONGITUDE = "long"; 
     public static final String LATITUDE = "lat"; 
    } 
} 

TaskDBHelper

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


public class TaskDBHelper extends SQLiteOpenHelper { 

    public TaskDBHelper(Context context) { 
     super(context, TaskContract.DB_NAME, null, TaskContract.DB_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase sqlDB) { 
     String sqlQuery = 
       String.format("CREATE TABLE %s (" + 
         "_id INTEGER PRIMARY KEY AUTOINCREMENT, " + 
         "%s TEXT" + " %s LONGITUDE" + "%s LATITUDE)", 
         TaskContract.POI_NAMES, TaskContract.Columns.POI, 
         TaskContract.LONGITUDES, TaskContract.Columns.LONGITUDE, 
         TaskContract.LATITUDES, TaskContract.Columns.LATITUDE); 

     Log.d("TaskDBHelper","Query to form table: "+sqlQuery); 
     sqlDB.execSQL(sqlQuery); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase sqlDB, int i, int i2) { 
     sqlDB.execSQL("DROP TABLE IF EXISTS "+TaskContract.POI_NAMES+TaskContract.LONGITUDES+TaskContract.LATITUDES); 
     onCreate(sqlDB); 
    } 
} 

и вот моя основная деятельность, где я добавить новые значения столбцов:

public class MainActivity extends ListActivity { 
    private ListAdapter listAdapter; 
    private TaskDBHelper helper; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     updateUI(); 
    } 

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

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.action_add_task: 
       AlertDialog.Builder builder = new AlertDialog.Builder(this); 
       builder.setTitle("Add a new point of interest"); 

       LinearLayout layout = new LinearLayout(this); 
       layout.setOrientation(LinearLayout.VERTICAL); 
       final TextView inputString1 = new TextView(this); inputString1.setText("Enter name:"); 
       final TextView inputString2 = new TextView(this); inputString2.setText("Enter longitude:"); 
       final TextView inputString3 = new TextView(this); inputString3.setText("Enter latitude:"); 
       final TextView inputString4 = new TextView(this); inputString4.setText("Enter a new point of interest:"); 

       final EditText inputField1 = new EditText(this); 
       final EditText inputField2 = new EditText(this); 
       final EditText inputField3 = new EditText(this); 
       layout.addView(inputString4); 
       layout.addView(inputString1); 
       layout.addView(inputField1); 
       layout.addView(inputString2); 
       layout.addView(inputField2); 
       layout.addView(inputString3); 
       layout.addView(inputField3); 
       builder.setView(layout); 


       builder.setPositiveButton("Add", new DialogInterface.OnClickListener() { 
        @Override 
        public void onClick(DialogInterface dialogInterface, int i) { 
         String poi = inputField1.getText().toString(); 
         String longit = inputField2.getText().toString(); 
         String lat = inputField3.getText().toString(); 

         helper = new TaskDBHelper(MainActivity.this); 
         SQLiteDatabase db = helper.getWritableDatabase(); 


         ContentValues values = new ContentValues(); 
         values.clear(); 
         values.put(TaskContract.Columns.POI,poi); 
         db.insertWithOnConflict(TaskContract.POI_NAMES,null,values,SQLiteDatabase.CONFLICT_IGNORE); 


         values.put(TaskContract.Columns.LONGITUDE,longit); 
         db.insertWithOnConflict(TaskContract.LONGITUDES,null,values,SQLiteDatabase.CONFLICT_IGNORE); 

         values.put(TaskContract.Columns.LATITUDE,lat); 
         db.insertWithOnConflict(TaskContract.LATITUDES,null,values,SQLiteDatabase.CONFLICT_IGNORE); 


         updateUI(); 
        } 
       }); 

       builder.setNegativeButton("Cancel",null); 

       builder.create().show(); 
       return true; 

      default: 
       return false; 
     } 
    } 

    private void updateUI() { 
     helper = new TaskDBHelper(MainActivity.this); 
     SQLiteDatabase sqlDB = helper.getReadableDatabase(); 
     Cursor cursor = sqlDB.query(TaskContract.POI_NAMES, 
       new String[]{TaskContract.Columns._ID, TaskContract.Columns.POI}, 
       null, null, null, null, null); 

     listAdapter = new SimpleCursorAdapter(
       this, 
       R.layout.task_view, 
       cursor, 
       new String[]{TaskContract.Columns.POI}, 
       new int[]{R.id.taskTextView}, 
       0 
     ); 

     this.setListAdapter(listAdapter); 
    } 

    public void onDoneButtonClick(View view) { 
     View v = (View) view.getParent(); 
     TextView taskTextView = (TextView) v.findViewById(R.id.taskTextView); 
     String poi = taskTextView.getText().toString(); 

     String sql = String.format("DELETE FROM %s WHERE %s = '%s'", 
         TaskContract.POI_NAMES, 
         TaskContract.Columns.POI, 
         poi); 


     helper = new TaskDBHelper(MainActivity.this); 
     SQLiteDatabase sqlDB = helper.getWritableDatabase(); 
     sqlDB.execSQL(sql); 
     updateUI(); 
    } 
} 

Я думаю, что проблема, когда я объявляю долгот и широт в TaskContract, как будто я их меняю так:

публичной статической финальной строки POI_NAMES = «задача»;

public static final Строка LONGITUDES = "tasks";

public static final String LATITUDES = "tasks";

это работает, но он помещает все в одну колонку.

Может кто-нибудь объяснить, что именно означает присвоение значениям «задачи» моей строке?

ответ

0

В вашем коде есть несколько ошибок - для справок в будущем вы можете проверить, что каждый метод делает here.

String.format("CREATE TABLE %s (" + 
         "_id INTEGER PRIMARY KEY AUTOINCREMENT, " + 
         "%s TEXT" + " %s LONGITUDE" + "%s LATITUDE)", 
         TaskContract.POI_NAMES, TaskContract.Columns.POI, 
         TaskContract.LONGITUDES, TaskContract.Columns.LONGITUDE, 
         TaskContract.LATITUDES, TaskContract.Columns.LATITUDE); 

Здесь «ТЕКСТ» относится к типу данных типа SQLite TEXT. SQLite не имеет типа данных LONGITUDE/LATITUDE. Список всех типов данных доступен here. В вашем случае вы можете использовать REAL для чисел с плавающей запятой или TEXT, если вы хотите сохранить координаты в виде строк (на момент ввода строк, поэтому я приведу пример с ним, но имейте в виду, что REAL обычно лучше подход). Кроме того, у вас есть только 4 заполнителя, но они содержат 6 параметров. Попробуйте что-то вроде этого:

String.format("CREATE TABLE %s (" + 
          "_id INTEGER PRIMARY KEY AUTOINCREMENT, " + 
          "%s TEXT" + " %s TEXT" + "%s TEXT)", 
          TaskContract.POI_NAMES, TaskContract.Columns.POI, 
          TaskContract.Columns.LONGITUDE, TaskContract.Columns.LONGITUDE); 

Это должно быть изменено слишком:

sqlDB.execSQL("DROP TABLE IF EXISTS "+TaskContract.POI_NAMES+TaskContract.LONGITUDES+TaskContract.LATITUDES); 

При удалении таблицы, вам нужно указать только его имя - в вашем случае это TaskContract.POI_NAMES. Добавление имен столбцов просто сделает код SQL неправильным, и ваш оператор будет отклонен (т. Е. Вернет ошибку).Сделать это следующим образом:

sqlDB.execSQL("DROP TABLE IF EXISTS " + TaskContract.POI_NAMES); 

Несколько вопросов здесь тоже:

ContentValues values = new ContentValues(); 
         values.clear(); 
         values.put(TaskContract.Columns.POI,poi); 
         db.insertWithOnConflict(TaskContract.POI_NAMES,null,values,SQLiteDatabase.CONFLICT_IGNORE); 


         values.put(TaskContract.Columns.LONGITUDE,longit); 
         db.insertWithOnConflict(TaskContract.LONGITUDES,null,values,SQLiteDatabase.CONFLICT_IGNORE); 

         values.put(TaskContract.Columns.LATITUDE,lat); 
         db.insertWithOnConflict(TaskContract.LATITUDES,null,values,SQLiteDatabase.CONFLICT_IGNORE); 

При вызове insertWithOnConflict вы предоставите имя таблицы и набор ключевых ценностей, которые представляют каждый из столбцов. Короче говоря, вам нужно позвонить insertWithOnConflict один раз для каждой записи, которую вы хотите вставить (не для каждого столбца в этой записи). Попробуйте этот код:

ContentValues values = new ContentValues(); 
values.put(TaskContract.Columns.POI,poi); 
values.put(TaskContract.Columns.LONGITUDE,longit); 
values.put(TaskContract.Columns.LATITUDE,lat); 
db.insertWithOnConflict(TaskContract.POI_NAMES,null,values,SQLiteDatabase.CONFLICT_IGNORE); 

После этих изменений вы можете удалить эти поля - они не будут нужны:

public static final String LONGITUDES = "longs"; 
public static final String LATITUDES = "lats"; 

Позвольте мне знать, если он работает или вам нужно больше помощи! :)

Смежные вопросы