Как добавить строки во время работы с SQLite? - PullRequest
0 голосов
/ 02 декабря 2018

Это мой первый проект для Android / sql, и я создаю приложение посещаемости с двумя базами данных.В DatabaseHelper есть таблица со списком студентов / профессоров.Другая, называемая coursesDatabase, имеет одну таблицу, в которой хранятся имена классов и их информация.Проблема, с которой я сталкиваюсь, состоит в том, что я хочу создать таблицу для каждого класса, в которой регистрируется посещаемость для этого конкретного класса, начиная с COL1 = STUDENT_NAME, затем добавляя каждый COL2 = LAST_NAME, COL3 = DATE1, COL4 = DATE2 и т. Д.с каждым столбцом даты создается каждый раз, когда профессор создает раздел посещаемости.Вот мой код, исключая нерелевантные завершенные методы:

public class CoursesDatabase extends SQLiteOpenHelper {
private static CoursesDatabase cd = null;

public static final int DATABASE_VERSION = 2;
public static final String DATABASE_NAME = "course_manager.db";
public static final String COURSES_TABLE_NAME = "COURSES";
public static final String KEY_ID = "ID";                         //column index 0
public static final String KEY_NAME= "COURSE_NAME";               //column index 1
public static final String KEY_CODE = "COURSE_CODE";              //column index 2
public static final String KEY_HOUR = "COURSE_HOUR";              //column index 3
public static final String KEY_MINUTE = "COURSE_MINUTE";          //column index 4
public static final String KEY_INSTRUCTOR = "COURSE_INSTRUCTOR";  //column index 5
public static final String IS_ON = "IS_ON";                       //column index 6

private CoursesDatabase(Context context){
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
    deleteAll();
    addCourse(new Course("354", "Software Engineering", "12345", 10, 30, "doctor doc"));
    addCourse(new Course("237", "CompSci 2", "13346", 11, 0, "john doe"));
}

public static CoursesDatabase getInstance(Context context){
    if (cd == null){
        cd = new CoursesDatabase(context);
    }
    return cd;
}

@Override
public void onCreate(SQLiteDatabase cd) {
    final String SQL_CREATE_USER_TABLE = "CREATE TABLE " + COURSES_TABLE_NAME + "(" +
            KEY_ID          +   " TEXT NOT NULL, "  +   // column 0
            KEY_NAME        +   " TEXT NOT NULL, "  +   // column 1
            KEY_CODE        +   " TEXT NOT NULL, "  +   // column 2
            KEY_HOUR        +   " INT, "            +   // column 3
            KEY_MINUTE      +   " INT, "            +   // column 4
            KEY_INSTRUCTOR  +   " TEXT,"            +   // column 5
            IS_ON           +   "INT DEFAULT 0);";      // column 6

    cd.execSQL(SQL_CREATE_USER_TABLE);
}

//Creates a table to log attendance for each class
String KEY_STUDENT_FIRST_NAME = "First_Name";
String KEY_STUDENT_LAST_NAME = "Last_Name";
public void newClassTable(SQLiteDatabase cd, Course course){
    String CLASS_TABLE_NAME = course.getId() + "-" + course.getName() + "-" + course.getHour() + ":" + course.getMinute();

    final String SQL_CREATE_CLASS_TABLE = "CREATE TABLE " + CLASS_TABLE_NAME + "(" +
            KEY_STUDENT_FIRST_NAME     +   " STRING NOT NULL, " +  // column 0
            KEY_STUDENT_LAST_NAME      +   " STRING NOT NULL);";   // column 1
    cd.execSQL(SQL_CREATE_CLASS_TABLE);
}

//takes the attendance of a student in course table. If the student does not exist in the course table, the student is then added.
public boolean attendStudentInCourse(Student student, Course course) {
    SQLiteDatabase cd = this.getWritableDatabase();

    //if professor has not turned on the course yet exit
    if (!course.isAvailable()) {
        return false;
    }

    return true;

}

Так что мой вопрос в том, какие методы я использую, чтобы создать новый столбец в конце таблицы классов, когда профессор нажимает на «новый сеанс»для этого класса?И как я смогу обновить эту конкретную последнюю строку, когда студент попробует метод attendStudentInCourse()?

1 Ответ

0 голосов
/ 02 декабря 2018

Итак, мой вопрос в том, какие методы я использую, чтобы создать новый столбец в конце таблицы классов, когда профессор нажимает «новый сеанс» для этого класса?

Вы можете добавить столбец в таблицу (с некоторыми условиями), используя

ALTER TABLE <your_table_name> ADD COLUMN <you_column_definition(e)>
  • Обратите внимание, что вы будете использовать метод execSQL , так как нет удобного методаиз-за редкости, что будет использоваться ALTER.

SQL как понял SQLite - ALTER TABLE прочтите это для условий / ограничений.

И как я смогу обновить эту конкретную последнюю строку, когда учащийся попытается применить метод методаStundentInCourse ()?

Предполагая, что вы имели в виду столбец, а не строкузатем

Обратите внимание, что вы можете использовать DEFAULT <default_value> для установки значения по умолчанию, которое будет применяться ко всем существующим строкам.

Если установить значение по умолчанию (я бы предположил, что новый сеанс изначальнов курсе 0 студентов) тогда не годитсяВы можете использовать запрос UPDATE.

Если вы имели в виду строку, то: -

Однако добавление столбца не добавляет строку, добавленный столбец применяется ко всем строкам.


Говоря все, что дизайн, вероятно, можно улучшить, чтобы: -

  • a) иметь единую базу данных, которая использует отношения, поскольку SQLite - это система управления реляционными базами данных (RDMS), предназначенная дляпревосходно справляются с отношениями между таблицами.
  • b) имеют отношения, исключающие сложность различного числа столбцов или списков в столбце (добавление столбцов и, таким образом, наличие динамической трудно читаемой схемы).
  • c) Нормализовать некоторые факторы, например, инструктора, так как, по-видимому, его необходимо вводить в строке и вполне можно дублировать и быть неэффективным.
  • , например, Длинное имя профессора Ихавеа потребует более 25байт каждый раз, когда он сохраняется, и может потребоваться проверка до 25 байтов при выполнении поиска / сравнения по строке.
    • Если вместо этого у вас есть таблица инструкторов, вам нужно будет только сохранить ссылку на инструктора (псевдоним rowid, скорее всего, будет очень подходящим столбцом для ссылки, поэтому обычно скрытый столбец rowidсуществует), тогда 25_ байт будут сохранены только один раз, тогда как эталон (максимум 8 байт (если у вас есть миллиарды инструкторов), приблизительно 1 байт для до 127 инструкторов) будет сохранен только для экономии места, сокращения ввода-вывода и увеличенияможно кэшировать.

Пример (с использованием необработанного SQL)

В качестве примера, возможно, рассмотрим следующее, которое использует: -

  • роль таблица ролей (студент-инструктор) (то есть у человека есть роль), поэтому есть
  • персона таблица для всех людей (их отношения (одинроль для многих людей) определение того, что они делают (инструктировать (инструктор), обучать (студент), помогать инструктировать (помощь инструктора) или администрировать)
    • Новые роли можно динамически добавлять, есливозникает необходимость
  • a курс таблица со статической информацией о курсе, названии, кодовом времени
  • и посещаемость таблицаэто таблица сопоставления, в которой хранится вся информация о посещаемости (все регистры посещаемости в одном).

- Записать одну базу данных с несколькими таблицами с отображением взаимосвязей или ссылками

- Записать одинбаза данных с несколькими таблицами с отображением отношений или ссылками

DROP TABLE IF EXISTS role;
DROP TABLE IF EXISTS person;
DROP TABLE IF EXISTS course;
DROP TABLE IF EXISTS attendance;
DROP VIEW IF EXISTS proposed_attendance_list;
DROP VIEW IF EXISTS non_attendance_list;

-- Create the role table
CREATE TABLE IF NOT EXISTS role (_id INTEGER PRIMARY KEY, role);
-- Add some roles
-- NOTE _id column is not specified so SQLite will assign a unqiue value 
-- assigned value will likely be 1, then likely 2, then likely 3........9,223,372,036,854,775,807 (highest)
-- NOTE no need for AUTOINCREMENT keyword and the resultant performance loss
-- NOTE _id is the column name that best suits Android (e.g. Cursor Adapters need this column name)
INSERT INTO ROLE (role) VALUES 
    ('Instructor'), -- id 1
    ('Student'), -- id 2
    ('Instructor Aid '), -- id 3
    ('Administrator') -- id 4
    -- !!!NOTE!!! you would not typically assume specific id
;

-- Create the Person table (Person will have a role - for simplicity of demo single role assumed)
CREATE TABLE IF NOT EXISTS person (_id INTEGER PRIMARY KEY, name TEXT, role INTEGER);

INSERT INTO person (name,role) VALUES
    ('Professor Plum',1), -- Instructor id = 1
    ('Tom Brown',2), -- Student id = 2
    ('Mary Smith',2), -- Student  id = 3
    ('Sue Barnes',2), -- Student id = 4
    ('Ty Pit',4), -- Admin id = 5
    ('Dr. J M Hardy',1), -- Instructor id = 6
    ('Matilda Dance',2), -- Student id = 7
    ('Fred Bloggs',3) -- Aid id = 8

;

CREATE TABLE IF NOT EXISTS course (
    _id INTEGER PRIMARY KEY, 
    course_name TEXT NOT NULL, 
    course_code TEXT NOT NULL, 
    course_hour TEXT NOT NULL, 
    course_minute TEXT, 
    course_time, 
    course_instructor INTEGER
);
INSERT INTO course (course_name, course_code, course_hour, course_minute, course_instructor) VALUES
    ('MATHS BASIC','M001','10','30',6), -- Maths with instructor Dr. J M Hardy id = 1
  ('MATHS APPLIED', 'M101','12','30',6), -- Applied Maths instructor Dr. J M Hardy id =2 
  ('MATHS ADVANCED','M011','11','00',1) -- Advanced Maths instructor Professor Plum id =3
;

CREATE TABLE IF NOT EXISTS attendance (course_reference INTEGER, person_reference INTEGER, attended INTEGER, PRIMARY KEY (course_reference, person_reference));
INSERT INTO attendance VALUES
    (1,6,0), -- Dr J M Hardy should attend (attended 0 = should attend, -1 if did not attend, 1 if did attend) course MATCHS BASIC
    (1,3,0), -- Mary Should attent Basic maths
    (1,7,0), -- Matilda should attend basic maths
    (1,8,0), -- Aid Fred should attend basic maths
    (3,1,1), -- Advanced maths Plum attended (taught it)
    (3,2,-1), -- Advanced maths Tom Brown missed
    (3,3,1), -- Advanced maths mary attended
    (3,8,1), -- Aid Fred attended
    (2,4,1), -- Applied Maths Sue attended
    -- (2,4,0) WOULD BE DUPLICATE SO NOT ALLOWED (INSERT OR IGNORE would skip, Note android SQliteDatabase insert method uses INSERT OR IGNORE)
    (2,3,0), -- Mary didn't attend as such but not flagged as did not attend (could just use 0 to indicate did not attend)
    (2,7,1), -- Applied Maths Matilda attended
    (2,6,0), -- Dr Hardy should attend
    (2,1,0), -- Prof Plum should attend
    (2,8,0) -- Fred Bloggs Admin should attend
;

-- Course attendace example listing the course details, the number of attendees and the list of attendees
-- Create as a view so that it can be resued (only need to type it out once)
CREATE VIEW IF NOT EXISTS proposed_attendance_list AS 
    SELECT 
        course.course_name, 
        course.course_code, 
        course.course_hour||':'||course.course_minute AS CourseTime, 
        count(attended) AS proposed_attendance, 
        group_concat(Person.name,' ,') AS peeople 
    FROM Course 
        JOIN attendance ON course._id = attendance.course_reference
        JOIN person ON attendance.person_reference = person._id
        JOIN role ON person.role = role._id
    -- GROUP BY course_hour, course_minute
    -- HAVING
    GROUP BY course_code
    ORDER BY course.course_code,role._id
;
-- Initial proposed course attendance
SELECT * FROM proposed_attendance_list;
-- Change some course codes
UPDATE course SET course_code = 'M201' WHERE course_code = 'M101';
UPDATE course SET course_code = 'M111' WHERE course_code = 'M011';
-- Modifed proposed course attendance
SELECT * FROM proposed_attendance_list;
  • Примечание комментарии (-)

Результаты

1.Начальная предлагаемая посещаемость курса

enter image description here

2.После изменения названия курса

enter image description here

Относительно изменения посещаемости

Первый другой способ написать письмо о непосещении в качестве демонстрации

CREATE VIEW IF NOT EXISTS non_attendance_list AS
    SELECT course_name, 
        course_code, 
        Person.name, 
        Person.role, 
        'Dear '||person.name||' our records show that you did''t attend Course '||course_code||' '||course_name||' rest of letter' AS letter_to_send
    FROM attendance
        JOIN course ON course_reference = course._id
        JOIN Person ON person_reference = Person._id
        JOIN Role ON Person.role = role._id
    WHERE attendance.attended < 1
    ORDER BY course_code
;

-- Initial letters
SELECT letter_to_send FROM non_attendance_list;

Результат

enter image description here

Пример изменения посещаемости

-- Set Mary as having attended M001 Basic maths
UPDATE attendance SET attended = 1 
    WHERE course_reference = (SELECT _id FROM course WHERE course_code = 
        'M001' -- value that would be changed to suit
    )
        AND person_reference = (SELECT _id FROM person WHERE name =
        'Mary Smith' -- value that would be changed to suit
        )
;
-- Letters after update
SELECT letter_to_send FROM non_attendance_list;

Результат (нет письма Марии по M001)

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...