Страница 37 из 39

Re: Урок 34. Хранение данных. SQLite

Добавлено: 03 июн 2015, 12:58
K1ng9
Всем привет, нужна помощь
SQLite связь один-ко-многим
не могу понять как реализовать и использовать ( прописать пример SELECT ) или как добавить 2-3-4 DB_TABLE в C_IDTASK
заранее спасибо (вопрос есть и в группе ВК fanDROID.info кому как удобнее ответить :D )

структуру я понимаю а как реализовать не могу найти

private static final String DB_CREATE =
"create table " + DB_TABLE + " ("
+ C_ID + " integer primary key autoincrement, " +
C_NAME + " text, " +
C_AWARD + " int, " +
C_DONE + " int" + ");";

private static final String DB_CREATE2 =
"create table " + DB_TABLE2 + " ("
+ C_IDAKK + " integer primary key autoincrement, " +
C_LOGIN + " text, " +
C_EMAIL + " int, " +
C_PASSWORD + " text, " +
C_COINS + " int, " +
C_IDTASK + " int, " +
"FOREIGN KEY(" + C_IDTASK + ") REFERENCES " + DB_TABLE +"(" + C_ID + ")"+ ");";

Re: Урок 34. Хранение данных. SQLite

Добавлено: 09 июн 2015, 10:18
dosssik
Ребята привет!
Вопрос немного не стандартный, из серии "Не работало, починил, но не понял почему заработало"=)

Повторял код урока, без копипаста, "ручками", и на выходе, при попытке прочитать что либо из базы данных получал ошибку "SQLiteException: no such table: mytable: ".
После 10 раза перепроверки заметил единственное отличие кода урока от своего. В конструкторе суперкласса DBHelper отличие в одной букве:
Мой код:

Код: Выделить всё

super(context,"myDb", null, 1 );
Хозяйский код:

Код: Выделить всё

super(context,"myDB", null, 1 );
Исправил - заработало. Вопрос - почему???) Насколько я понимаю, имя базы данных можно назначать любое, тобишь этот параметр метода суперкласса - просто строковое значение. Во всем коде нет ни одного обращения к базе данных по имени. Соответственно, очень хочется понять, причину ошибки, и как это все-таки работает.

На всякий случай - вот полный код:

Код: Выделить всё

package com.dosssik.andrey.sqlsample;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;


public class MainActivity extends Activity implements View.OnClickListener {

    /*private static final String DATABASE_NAME = "database.db";
    private static final String DATABASE_TABLE = "mainTable";
    private static final String DATABASE_CREATE = "create table " + DATABASE_TABLE
            + "( id integer primary key autoincrement, " + "column_one not null);";
    SQLiteDatabase myDb;*/

    final String LOG_TAG = "myLogs";

    Button btnRead, btnAdd, btnClear;
    EditText edName, edMail;
    DBHelper dbHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnAdd = (Button) findViewById(R.id.add_btn);
        btnAdd.setOnClickListener(this);
        btnRead = (Button) findViewById(R.id.read_btn);
        btnRead.setOnClickListener(this);
        btnClear = (Button) findViewById(R.id.clear_btn);
        btnClear.setOnClickListener(this);

        edMail = (EditText) findViewById(R.id.ed_mail);
        edName = (EditText) findViewById(R.id.ed_name);

        dbHelper = new DBHelper(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View view) {

        // Шта это?
        ContentValues cv = new ContentValues();

        String name = edName.getText().toString();
        String email = edMail.getText().toString();

        // Подключение к ДБ
        SQLiteDatabase db = dbHelper.getWritableDatabase();

        switch (view.getId()) {
            case R.id.add_btn:
                Log.d(LOG_TAG, "--- insert into myTable ---");
                // Подготавливаем данные, приводим к виду ключ-значение
                cv.put("name", name);
                cv.put("email", email);
                // Вставляем запись, и получаем ее ID
                long rowId = db.insert("mytable", null, cv);
                Log.d(LOG_TAG, "Row inserted, ID = " + rowId);
                break;

            case R.id.read_btn:
                Log.d(LOG_TAG, "--- Rows in mytable: ---");
                Cursor c = db.query("mytable", null, null, null, null, null, null);

                if(c.moveToFirst()) {
                    int idColIndex = c.getColumnIndex("id");
                    int nameColIndex = c.getColumnIndex("name");
                    int emailColIndex = c.getColumnIndex("email");

                    do {
                        Log.d(LOG_TAG, "Id = " + c.getInt(idColIndex) +
                                ", name = " + c.getString(nameColIndex) + ", email = " + c.getString(emailColIndex));
                    } while (c.moveToNext());

                } else Log.d(LOG_TAG, "0 rows");
                c.close();
                break;
            case R.id.clear_btn:
                Log.d(LOG_TAG, ("--- Clear mytable ---"));
                int cleatCount = db.delete("mytable", null, null);
                Log.d(LOG_TAG, ("--- i killed everything ---"));
                break;

        }
        dbHelper.close();
    }

    class DBHelper extends SQLiteOpenHelper {

        public DBHelper (Context context) {
            super(context,"myDb", null, 1 );
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.d(LOG_TAG, "--- onCreate db ---");
            db.execSQL("create table mytable (" + "id integer primary key autoincrement,"
                    + "name text," + "email text" + ");");
            Toast.makeText(getApplicationContext(), "db", Toast.LENGTH_SHORT).show();

        }

        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

        }
    }

}
Заранее спасибо!

Re: Урок 34. Хранение данных. SQLite

Добавлено: 09 июн 2015, 15:32
klblk
Нужны логи. Но думаю если удалить и заново установить приложение все будет работать. Вангую некорректное создание бары под первоначальным именем.

Re: Урок 34. Хранение данных. SQLite

Добавлено: 10 июн 2015, 15:55
dosssik
klblk писал(а):Нужны логи. Но думаю если удалить и заново установить приложение все будет работать. Вангую некорректное создание бары под первоначальным именем.
Слушай, спасибо тебе огромное! Всю голову успел сломать.

Прочитав твое сообщение установил на телефон, заработало. Снес на эмуляторе, заново поставил - заработало. :?
Сразу за благодарностью - вопрос: что за баг такой интересный? Из за чего происходит некорректная установка, как часто происходит, и самое главное как по логам выяснить, что это не в коде проблема..?

Re: Урок 34. Хранение данных. SQLite

Добавлено: 10 июн 2015, 16:22
Foenix
это не баг
нужно знать что такое версия базы данных вообще-то
и правильно это все программировать.

Re: Урок 34. Хранение данных. SQLite

Добавлено: 11 июн 2015, 07:00
klblk
dosssik писал(а):
klblk писал(а):Нужны логи. Но думаю если удалить и заново установить приложение все будет работать. Вангую некорректное создание бары под первоначальным именем.
Слушай, спасибо тебе огромное! Всю голову успел сломать.

Прочитав твое сообщение установил на телефон, заработало. Снес на эмуляторе, заново поставил - заработало. :?
Сразу за благодарностью - вопрос: что за баг такой интересный? Из за чего происходит некорректная установка, как часто происходит, и самое главное как по логам выяснить, что это не в коде проблема..?
это не баг. Скорее всего когда писал код запускал промежуточную не готовую версию, где вариант базы отличался от финального.

По логам и ошибкам смотри сюда viewtopic.php?f=60&t=3198

Re: Урок 34. Хранение данных. SQLite

Добавлено: 11 июн 2015, 20:35
dosssik
klblk писал(а):
dosssik писал(а):
klblk писал(а):Нужны логи. Но думаю если удалить и заново установить приложение все будет работать. Вангую некорректное создание бары под первоначальным именем.
Слушай, спасибо тебе огромное! Всю голову успел сломать.

Прочитав твое сообщение установил на телефон, заработало. Снес на эмуляторе, заново поставил - заработало. :?
Сразу за благодарностью - вопрос: что за баг такой интересный? Из за чего происходит некорректная установка, как часто происходит, и самое главное как по логам выяснить, что это не в коде проблема..?
это не баг. Скорее всего когда писал код запускал промежуточную не готовую версию, где вариант базы отличался от финального.

По логам и ошибкам смотри сюда viewtopic.php?f=60&t=3198
Большое спасибо за ссылку, сейчас засяду смотреть
Если не изменяет память - приложение в процессе написания не запускал. А каким образом может отличаться вариант базы? Вы имеете ввиду, что в процессе написания я мог создать базу "myDB", а потом обращался к "myDb", что собственно и провоцировало ошибку? Заранее прошу прощение за корявую формулировку вопроса :geek:

Re: Урок 34. Хранение данных. SQLite

Добавлено: 11 июн 2015, 20:40
dosssik
Foenix писал(а):это не баг
нужно знать что такое версия базы данных вообще-то
и правильно это все программировать.
А можно, пожалуйста, поподробнее? С SQLite раньше не сталкивался, и в целом опыт с базами данных ограничивается упражнениями и видеоуроками с YouTube. Соответственно не совсем понимаю какая связь между версией и названием БД. Буду очень признателен, если объясните. очень хочется разобраться
Спасибо

Re: Урок 34. Хранение данных. SQLite

Добавлено: 12 июн 2015, 00:21
Foenix
Солнце, так уроки же тут есть.. там же описаны эти основы.

Re: Урок 34. Хранение данных. SQLite

Добавлено: 23 июн 2015, 14:37
dosssik
Ребята, снова привет, и снова вопрос.

Вопрос связан с конструкторами класса DBHelper.
У класса SQLiteOpenHelper, от которого мы наследуем DBHelper, имеется два дефолтных конструктора:

Код: Выделить всё

public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {
        throw new RuntimeException("Stub!");
    }

    public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
        throw new RuntimeException("Stub!");
    }
В коде урока же, мы создаем свой конструктор с единственными параметром на вход (конеткст), и конструктору суперкласса вручную передаем константы (имя базы данных, версию и тд):

Код: Выделить всё

 public DBHelper(Context context) {
      // конструктор суперкласса
      super(context, "myDB", null, 1);
    }
Соответственно вопрос - почему мы пишем такую конструкцию, когда можно просто в методе onCreate нашей активити передать все эти параметры дефолтному конструктору? Тобишь:

Код: Выделить всё

dbHelper = new DBHelper(this, "myDb", null, 1)
Не очень понимаю смысл этого действия, буду очень признателен, если объясните. Понимаю, что возможно вопрос дурацкий, но мы же здесь, что бы учиться, так?)
Заранее спасибо

Re: Урок 34. Хранение данных. SQLite

Добавлено: 24 июн 2015, 00:28
Foenix
в данном случае это сделано больше для удобства, мы передаем только изменяющийся параметр, а о других создающий класс не должен знать - зачем ему имя базы, к примеру? а если вы имя поменяете, то по всей проге шарить и искать где вы его упоминали, а тут - все в одном месте..

Re: Урок 34. Хранение данных. SQLite

Добавлено: 25 июн 2015, 16:31
dosssik
Foenix писал(а):в данном случае это сделано больше для удобства, мы передаем только изменяющийся параметр, а о других создающий класс не должен знать - зачем ему имя базы, к примеру? а если вы имя поменяете, то по всей проге шарить и искать где вы его упоминали, а тут - все в одном месте..
Спасибо, что разъяснили! Раньше не встречал такой прием

Re: Урок 34. Хранение данных. SQLite

Добавлено: 20 июл 2015, 12:05
niklas1987
Здрасьте. Объясните пожалуйста вот этот help:

2.1 Determination Of Column Affinity

The affinity of a column is determined by the declared type of the column, according to the following rules in the order shown:

1. If the declared type contains the string "INT" then it is assigned INTEGER affinity.


2. If the declared type of the column contains any of the strings "CHAR", "CLOB", or "TEXT" then that column has TEXT affinity. Notice that the type VARCHAR contains the string "CHAR" and is thus assigned TEXT affinity.

3. If the declared type for a column contains the string "BLOB" or if no type is specified then the column has affinity NONE.

4. If the declared type for a column contains any of the strings "REAL", "FLOA", or "DOUB" then the column has REAL affinity.

Otherwise, the affinity is NUMERIC.

Note that the order of the rules for determining column affinity is important. A column whose declared type is "CHARINT" will match both rules 1 and 2 but the first rule takes precedence and so the column affinity will be INTEGER.

Я так понял, что если я хочу в таблицу закинуть int, string, float и double, то при создании таблица я должен указать следующий текст:

String s = "20.07.2015"
int i = 5;
float f = 0.833f;
double d = 3.5;

Код: Выделить всё

class DBHelper extends SQLiteOpenHelper {

        public DBHelper(Context context) {
            super(context, "myDB", null, 1);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.d("onCreate", "DataBase");
            db.execSQL("CREATE TABLE myTrips ("
                    + "id integer primary key autoincrement,"
                    + "date text,"
                    + "days integer,"
                    + "specificWeight real,"
                    + "factor real," + ");");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        }
    }

Код: Выделить всё

public void onSaveClick(View v){
        Log.d("Save", "Click");
        cv = new ContentValues();        

        db = dbhelper.getWritableDatabase();
        cv.put("date", s);
        cv.put("days", i);
        cv.put("specificWeight", f);
        cv.put("factor", d);
        
        rowID = db.insert("myTrips", null, cv);
        Log.d("ME", "row inserted, ID = " + rowID);

        Toast.makeText(TripsRecords.this, "Сохранено", Toast.LENGTH_SHORT).show();
    }

    public void onReadClick(View v){
        Log.d("Read", "Click");
        Cursor c = db.query("myTrips", null, null, null, null, null, null);

        if(c.moveToFirst()){
            int idColIndex = c.getColumnIndex("id");
            int dateColIndex = c.getColumnIndex("date");
            int daysColIndex = c.getColumnIndex("days");
            int specificWeightColIndex = c.getColumnIndex("specificWeight");            
            int factorColIndex = c.getColumnIndex("factor");

            do {
                Log.d("ME",
                        "ID = " + c.getInt(idColIndex) +
                        ", date = " + c.getString(dateColIndex) +
                        ", days = " + c.getString(daysColIndex) +
                        ", specificWeight = " + c.getString(specificWeightColIndex) +
                        ", factor = " + c.getString(factorColIndex));
            }while(c.moveToNext());
        }else{
            Log.d("ME", "Нет записей");
        }
        c.close();
        dbhelper.close();
    }
Правильно ли создана таблица?

Re: Урок 34. Хранение данных. SQLite

Добавлено: 20 июл 2015, 12:38
Foenix
в документации говорится, что есть только 4 типа данных в sqlite - целое, реальное, блоб и текст. Приведенный отрывок о том, что вы можете описывать типы при создании таблицы по-разному, и приведены правила, которым воспользуется sqlite, чтобы привести эти ваши типы к своим. БОльше там ничего в этом отрывке другого не написано, к данным это отношения не имеет, что вы там хотите туда записать и так далее.
Более того, если вы объявили поле как целое, например, то можете без уведомлений об ошибках со стороны СУБД запульнуть туда хоть строку, хоть черта лысого. По сути все равно в sqlite все типы сводятся к одному - text.

Чтобы не путаться, лично я придерживаюсь при создании таблицы обозначений типов с сайта sqlite:
INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value.

REAL. The value is a floating point value, stored as an 8-byte IEEE floating point number.

TEXT. The value is a text string, stored using the database encoding (UTF-8, UTF-16BE or UTF-16LE).

BLOB. The value is a blob of data, stored exactly as it was input.

Re: Урок 34. Хранение данных. SQLite

Добавлено: 21 окт 2015, 12:59
anapel
Подскажите как можно просмотреть БД созданную моим приложением ? в /data/..... попасть не могу говорит нет доступа

Re: Урок 34. Хранение данных. SQLite

Добавлено: 21 окт 2015, 15:41
Foenix
для этого нужен рут
а если его нет - то эмулятор

Re: Урок 34. Хранение данных. SQLite

Добавлено: 15 мар 2016, 21:33
Кошки Рулят
Про даты никак не могу понять.
Мне нужно в БД хранить дату

Код: Выделить всё

//Создаю таблицу как в учили в уроке
public static final String KEY_DATA = "dataDoc";
...
      db.execSQL("create table " + TABLE_MSG + "(" + KEY_ID
                + " integer primary key," + KEY_DATA + " text," +

// Записываю тоже как в уроке учили
  contentValues.put(DbHelper.KEY_DATA, "2016-01-01");
   ...
  database.insert(DbHelper.TABLE_MSG, null, contentValues);

//теперь хочу вывести данные БД в список

           do {

                View stroka = ltInflater.inflate(R.layout.stroka, linLayout, false);
                TextView datаDoc = (TextView) stroka.findViewById(R.id.txtDateDoc);
                datаDoc.setText("Дата: " + cursor.getInt(DataDocIndex)); //
                linLayout.addView(stroka);

            } while (cursor.moveToNext());
На выходе - Дата: 2016
Какую строку при этом записывать не суть (01.01.2016, 2016/01/01, 01 января 2016, ... ) - на выходе все равно приведенная к числу строка.
Что я не так делаю?
Нужно записывать как-то иначе или извлекать в каком-то другом виде?


П.С. Ногами не пинайте, плз. После 1С тяжело понять что она хочет ...

Re: Урок 34. Хранение данных. SQLite

Добавлено: 16 мар 2016, 22:27
Foenix
сохраняй дату либо в формате 20160131
либо в виде лонга кол-во секунд с 71 года, кажется нужно Calendar использовать, не помню точно.
Мне удобнее первый формат, сразу видно какая дата, сортировать удобно и т.д. многие субд понимают этот фортмат как универсальный. А второй - когда дата содержит время, например, тайстемпы и т.д.

Re: Урок 34. Хранение данных. SQLite

Добавлено: 19 мар 2016, 23:06
mishaberces
Для начала хочу поблагодарить за проект. Уроки понравились есть что-почитать и поучится.

Помогите плиз новичку. Написал небольшое приложение с использованием баз данных. При первом запуске программы вилетает сообщение о ошибке но приложение дальше работает после нажатие на Ок. Ноут у меня слабинький поэтому эмулятор не использую, тестирую сразу на телефоне или планшете.
Лог ошибки:

Код: Выделить всё

03-19 21:38:47.069 28649-28649/com.example.misha.fizmap10 E/AndroidRuntime: FATAL EXCEPTION: main
                                                                            Process: com.example.misha.fizmap10, PID: 28649
                                                                            java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.misha.fizmap10/com.example.misha.fizmap10.main}: java.lang.IllegalArgumentException: the bind value at index 1 is null
                                                                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2358)
                                                                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2410)
                                                                                at android.app.ActivityThread.access$800(ActivityThread.java:155)
                                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1331)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:110)
                                                                                at android.os.Looper.loop(Looper.java:193)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5388)
                                                                                at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                at java.lang.reflect.Method.invoke(Method.java:515)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:655)
                                                                                at dalvik.system.NativeStart.main(Native Method)
                                                                             Caused by: java.lang.IllegalArgumentException: the bind value at index 1 is null
                                                                                at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:164)
                                                                                at android.database.sqlite.SQLiteProgram.bindAllArgsAsStrings(SQLiteProgram.java:200)
                                                                                at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
                                                                                at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1339)
                                                                                at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1186)
                                                                                at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1057)
                                                                                at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1225)
                                                                                at com.example.misha.fizmap10.main.onCreate(main.java:201)
                                                                                at android.app.Activity.performCreate(Activity.java:5280)
                                                                                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
                                                                                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2322)
                                                                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2410) 
                                                                                at android.app.ActivityThread.access$800(ActivityThread.java:155) 
                                                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1331) 
                                                                                at android.os.Handler.dispatchMessage(Handler.java:110) 
                                                                                at android.os.Looper.loop(Looper.java:193) 
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5388) 
                                                                                at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                                at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:655) 
                                                                                at dalvik.system.NativeStart.main(Native Method) 
При повторном запуске приложения на девайсе ошибка больше не возникает.
У меня подозрение что ошибка возникает при создании базы.

Клас базы

Код: Выделить всё

class DBHelper extends SQLiteOpenHelper {

    public final String TABLE_BAZE = "table_fizmat";

    public DBHelper(Context context) {
        // конструктор суперкласса
        super(context, "myDB1", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        // создаем таблицу с полями
        db.execSQL("create table " + TABLE_BAZE + " ("
                + "id integer primary key autoincrement,"
                + "grupp text,"
                + "predmet text, vykladach text, typpary integer, denj integer, nomerpary integer, auditorija text, chyseln integer, predmet_k text" + ");");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}
П.С. На телефонах HTC из-за ошибки не стартует вообще.

Re: Урок 34. Хранение данных. SQLite

Добавлено: 20 мар 2016, 23:32
Foenix
at com.example.misha.fizmap10.main.onCreate(main.java:201)
а тут что?