Задача База данных 5
Работа добавлена на сайт bukvasha.net: 2015-10-29Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
от 25%
договор
|
Содержание
1) Введение………………………………………………………………………...3
2) Задача
a) Предметная область и ER-диаграмма……………….………………………………………………..4
b) Физическая модель данных (макеты таблиц)…………………………. 5
c) Список явных ограничений целостности……………………………………………………………….6
3) Описание приложения
a) Функции и процедуры, а так же связи.......………………………...……7
b) Классы, их методы и поля класса………………………………………25
4) Описание функционирования базы данных
a) Процедуры и функции по реализации ограничений целостности, включая SQL запросы……………………………………………….......28
b) SQL запросы по ведению электронного аналога документа…………………………………………………………….…..29
5) Описание экранных форм……………………………………………………...30
6) Руководство по эксплуатации………………………………………………....31
7) Заключение…………………………………………………………………..….32
8) Список литературы………………………………………………………..……33
9) Приложение……………………………………………………………….….…34
Введение
Данная курсовая есть результат работы, выполненной в ходе изучения дисциплины “Базы данных”. В качестве задания необходимо создать программу, предназначенную для работы с базой данных, содержащей в себе информацию об учебных планах. На мой взгляд, были выполнены все требования и пожелания преподавателя касаемо функционирования и представления данных. Работа была сопряжена с «двигателем» базы данных SQLite, средой QT, и генератором отчётов eXaro. Были реализованы необходимые запросы для функционирования базы, а также реализована возможность отображения в отчёте только тех данных, которые попали в результат поиска, что значительно повышает ценность данного приложения.
Описание предметной области
Разработанное приложение предназначено для ведения базы данных, содержащей в себе информацию об учебных планах. С помощью этого приложения можно добавлять и удалять из базы дисциплины, преподавателей, студентов и учебные планы, диски, просматривать содержимое базы данных и многое др. Выходным документом является отчёт, который формируется в зависимости от выбранного студента. База отвечает на вопросы: какие дисциплины будет вести преподаватель у студентов, обучающихся по индивидуальному плану в 2003 году? С какими студентами, обучающимися по индивидуальному плану, предстоит работать преподавателю по предмету «Компьютерная графика»? Нужно ли проводить прием экзамена по дисциплине «БД» у студента Сидорова К.Н.? Сколько часов лаб.работ необходимо провести со студентом Петровым В.С. по дисциплине «БД»?
Объекты обладают следующими связями:
1) Дисциплины
a) Код дисциплины
b) Название дисциплины
2) Студенты
a) Код студента
b) Имя студента
c) Форма обучения
d) Год поступления
3) Преподаватели
a) Код преподавателя
b) Имя преподавателя
4) Учебные ланы
a) Код плана
b) Название плана
c) Год утверждеиия
d) Продолжительность обучения
5) Студент-План
a) Код студента
b) Код плана
Студент может иметь только один учебный план, а план может иметь неограниченное количество студентов.
6) Дисциплина-преподаватель
a) Код предмета
b) Код преподавателя
У дисциплины может быть только один преподаватель, а преподаватель может преподавать несколько дисциплин.
7) Дисциплина-План
a) Код дисциплины
b) Код плана
c) Курс
d) Лекции
e) Лаб.работы
f) Практики
g) Зачёт
h) Экзамен
У учебного плана может быть до шести одинаковых дисциплин (в зависимости от курса), у дисциплины может быть неограниченное количество учебных планов.
Физическая модель данных (макеты таблиц)
Объекты обладают следующими связями:
1) Дисциплины
Disciplina | |
Код | Название |
ID_disc* | a_ disc |
I | A(20) |
2) Студенты
Student | |||
Код | ФИО | Форма обуч. | Год поступления |
ID_stud* | a_stud | b_stud | year_stud |
I | A(30) | A(5) | I |
3) Преподаватели
Prepodavatel | |
Код | ФИО |
ID_prep* | а_prep |
I | A(30) |
4) Учебные планы
Plan | |||
Код | Название | Год | Продолжит. обуч. |
ID_plan* | b_plan | year_plan | prod_year |
I | A(30) | I | I |
5) Студент-План
Inf_Stud | |
Код студента | Код плана |
ID_stud* | ID_plan |
I | I |
6) Дисциплина-Преподаватель
Inf_Disc | |
Код дисциплины | Код преподавателя |
ID_disc * | ID_prep |
I | I |
7) Дисциплина-Преподаватель
Inf_Plan | |||||||
Код дисциплины | Код плана | Курс | Лекц. | Лаб. | Практ. | Зачёт | Экзамен |
ID_disc * | ID_prep* | kurs | lec | labs | prakt | zach | exam |
I | I | I | I | I | I | I | I |
список явных ограничений целостности
1) Не может быть больше одной дисциплины с одинаковым названием.
2) Не может быть двух и более одинаковых учебных планов.
3) Не может быть удалён студент, для которого определён учебный план. При удалении студента необходимо удалять связанные поля в таблице «Студент-План».
4) При удалении дисциплины необходимо удалять также связанные поля в таблице «Дисциплина-Преподаватель» и «Дисциплина-План».
5) При удалении учебного плана необходимо также удалять связанные поля в таблице «Дисциплина-План» и «Студент-План».
6) При удалении преподавателя необходимо также удалять связанные поля в таблице «Дисциплина-Преподаватель».
7) Нельзя добавлять связи для несуществующих студентов, преподавателей, планов и дисциплин.
функции и процедуры
Основной класс MainWindow отвечает за соединение с базой данных, а также за правильное отображение, редактирование и поиск данных. Пять зависимых класса визуально облегчают представление и редактирование данных. Основной класс содержит главные функции и процедуры для работы с базой.
Соединение с базой выполняется следующим образом:
db=QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("baza.db ");
db.open();
Отображение таблиц:
//Вывод таблицы
Disciplina
Disciplina=new QSqlTableModel(0,db);
Disciplina->setTable("Disciplina");
Disciplina->select();
Disciplina->setEditStrategy(QSqlTableModel::OnManualSubmit);
ui->disc_viev->setModel(Disciplina);
ui->disc_viev->setColumnHidden(0,true);
//
Вывод
таблицы
Prepodavatel
Prepodavatel=new QSqlTableModel(0,db);
Prepodavatel->setTable("Prepodavatel");
Prepodavatel->select();
Prepodavatel->setEditStrategy(QSqlTableModel::OnManualSubmit);
ui->prep_viev->setModel(Prepodavatel);
ui->prep_viev->setColumnHidden(0,true);
//
Вывод
таблицы
Student
Student=new QSqlTableModel(0,db);
Student->setTable("Student");
Student->select();
Student->setEditStrategy(QSqlTableModel::OnManualSubmit);
ui->stud_viev->setModel(Student);
ui->stud_viev->setColumnHidden(0,true);
//
Вывод
таблицы
Plan
Plan=new QSqlTableModel(0,db);
Plan->setTable("Plan");
Plan->select();
Plan->setEditStrategy(QSqlTableModel::OnManualSubmit);
ui->plan_viev->setModel(Plan);
ui->plan_viev->setColumnHidden(0,true);
//
Вывод
таблицы
Prep_Plan
Prep_Plan=new QSqlTableModel(0,db);
Prep_Plan->setTable("Prep_Plan");
Prep_Plan->select();
Prep_Plan->setEditStrategy(QSqlTableModel::OnManualSubmit);
//
Вывод
таблицы
Inf_Stud
Inf_Stud=new QSqlTableModel(0,db);
Inf_Stud->setTable("Inf_Stud");
Inf_Stud->select();
Inf_Stud->setEditStrategy(QSqlTableModel::OnManualSubmit);
//
Вывод
таблицы
Inf_Disc
Inf_Disc=new QSqlTableModel(0,db);
Inf_Disc->setTable("Inf_Disc");
Inf_Disc->select();
Inf_Disc->setEditStrategy(QSqlTableModel::OnManualSubmit);
model44.setQuery("SELECT b_disc,b_prep FROM Prepodavatel, Disciplina, Inf_Disc WHERE Prepodavatel.ID_prep=Inf_Disc.ID_prep AND Inf_Disc.ID_disc=Disciplina.ID_disc");
ui->tableView_2->setModel(&model44);
//
Вывод
таблицы
отчёт
QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery("SELECT b_disc,b_stud,c_stud,b_prep,b_plan,year_plan,year_prod,kurs,lec, labs, prakt, zach, exam FROM Disciplina,Student,Prepodavatel,Plan,Prep_Plan,Inf_Stud,Inf_Disc WHERE (Disciplina.ID_disc=Inf_Disc.ID_disc) AND (Prepodavatel.ID_prep=Inf_Disc.ID_prep) AND (Inf_Stud.ID_stud=Student.ID_stud) AND (Plan.ID_plan=Inf_Stud.ID_plan) AND (Prep_Plan.ID_disc=Disciplina.ID_disc) AND (Prep_Plan.ID_plan=Plan.ID_plan)");
ui->tableView->setModel(model);
Отображение
кнопок
:
ui->add_new_stud->setEnabled(false);
ui->del_new_stud->setEnabled(false);
ui->add_nagr->setEnabled(false);
ui->ok_nagruz->setEnabled(false);
ui->del_nagruz->setEnabled(false);
ui->ok_nagruz->setEnabled(false);
Сигналы:
//Сигналы для вкладки "Дисциплины и Преподаватели"
QObject::connect(ui->add_disc,SIGNAL(clicked()),this,SLOT(add_dis()));
QObject::connect(ui->del_disc,SIGNAL(clicked()),this,SLOT(del_dis()));
QObject::connect(ui->ok_disc,SIGNAL(clicked()),this,SLOT(ok_disc()));
QObject::connect(ui->disc_prep,SIGNAL(clicked()),this,SLOT(disc_prep()));
QObject::connect(ui->add_prep,SIGNAL(clicked()),this,SLOT(add_prep()));
QObject::connect(ui->del_prep,SIGNAL(clicked()),this,SLOT(del_prep()));
QObject::connect(ui->ok_prep,SIGNAL(clicked()),this,SLOT(ok_prep()));
//Сигналы для вкладки "Студенты и Учебные планы"
QObject::connect(ui->add_plan,SIGNAL(clicked()),this,SLOT(add_plan()));
QObject::connect(ui->del_plan,SIGNAL(clicked()),this,SLOT(del_plan()));
QObject::connect(ui->ok_plan,SIGNAL(clicked()),this,SLOT(ok_plan()));
QObject::connect(ui->can_plan,SIGNAL(clicked()),this,SLOT(can_plan()));
QObject::connect(ui->add_stud,SIGNAL(clicked()),this,SLOT(add_stud()));
QObject::connect(ui->del_stud,SIGNAL(clicked()),this,SLOT(del_stud()));
QObject::connect(ui->ok_stud,SIGNAL(clicked()),this,SLOT(ok_stud()));
QObject::connect(ui->can_stud,SIGNAL(clicked()),this,SLOT(can_stud()));
QObject::connect(ui->add_new_stud,SIGNAL(clicked()),this,SLOT(add_new_stud()));
QObject::connect(ui->del_new_stud,SIGNAL(clicked()),this,SLOT(del_new_stud()));
QObject::connect(ui->plan_viev,SIGNAL(clicked(QModelIndex)), this,
this,SLOT(plan_and_students()));
QObject::connect(ui->add_nagr,SIGNAL(clicked()),this,SLOT(add_nagr()));
QObject::connect(ui->del_nagruz,SIGNAL(clicked()),this,SLOT(del_nagruz()));
QObject::connect(ui->ok_nagruz,SIGNAL(clicked()),this,SLOT(ok_nagruz()));
QObject::connect(ui->stud_viev,SIGNAL(clicked(QModelIndex)),this,SLOT(st_viev()));
QObject::connect(ui->listView,SIGNAL(clicked(QModelIndex)),this,SLOT(st()));
QObject::connect(ui->nagruz_viev_2,SIGNAL(clicked(QModelIndex)),this,SLOT(izm_nag()));
ui->add_new_stud->setEnabled(false);
ui->del_new_stud->setEnabled(false);
ui->add_nagr->setEnabled(false);
ui->ok_nagruz->setEnabled(false);
ui->del_nagruz->setEnabled(false);
ui->ok_nagruz->setEnabled(false);
//
Сигналы
для
вкладки
"
Отчёт
"
QObject::connect(ui->Refresh,SIGNAL(clicked()),this,SLOT(Refresh()));
QObject::connect(ui->Report,SIGNAL(clicked()),this,SLOT(Report()));
ComboBox
для
вкладки
"
Отчёт
"
:
QSqlQuery q("select distinct b_stud from Student");
int i=0;
QString str;
while(q.next())
{
str=q.value(0).toString();
ui->comboBox_2->addItem(str,i);
i++;
}
Добавить запись:
//Описание функции кнопки Добавить
void
MainWindow
::
add
_
dis
()
{
add_disc form;
form.exec();
Disciplina->select();
}
void MainWindow::add_prep()
{
add_prepod form;
form.exec();
Prepodavatel->select();
}
void MainWindow::add_plan()
{
Plan->insertRecord(-1,QSqlRecord::QSqlRecord());
}
void MainWindow::add_stud()
{
Student->insertRecord(-1,QSqlRecord::QSqlRecord());
}
void MainWindow::add_nagr()
{
Prep_Plan->insertRecord(-1,QSqlRecord::QSqlRecord());
add_nagruz form;
form.exec();
Prep_Plan->select();
int a=ui->plan_viev->currentIndex().row();
QSqlRecord record1=Plan->record(a);
model1.setQuery(tr("SELECT b_disc,kurs,lec,labs,prakt,zach,exam FROM Disciplina, Plan, Prep_Plan WHERE Disciplina.ID_disc=Prep_Plan.ID_disc AND Prep_Plan.ID_plan=Plan.ID_plan AND (b_plan=\"%1\") AND (year_plan=\"%2\") AND (year_prod=\"%3\")").arg(record1.value("b_plan").toString()).arg(record1.value("year_plan").toInt()).arg(record1.value("year_prod").toInt()));
ui->nagruz_viev_2->setModel(&model1);
}
void MainWindow::add_new_stud()
{
int a=ui->plan_viev->currentIndex().row();
QSqlRecord record1=Plan->record(a);
int n=ui->stud_viev->currentIndex().row();
QSqlRecord record2=Student->record(n);
int str=record1.value("ID_plan").toInt();
int str1=record2.value("ID_stud").toInt();
QSqlQuery query;
query.prepare("INSERT INTO Inf_Stud (ID_stud, ID_plan)"
"VALUES (:id1, :id2)");
query.bindValue(":id1",str1);
query.bindValue(":id2",str);
query.exec();
model11.setQuery(tr("SELECT b_stud FROM Student, Inf_Stud, Plan WHERE (Student.ID_stud=Inf_Stud.ID_stud) AND (Inf_Stud.ID_plan=Plan.ID_plan) AND (b_plan=\"%1\") AND (year_plan=\"%2\") AND (year_prod=\"%3\")").arg(record1.value("b_plan").toString()).arg(record1.value("year_plan").toInt()).arg(record1.value("year_prod").toInt()));
ui->listView->setModel(&model11);
Inf_Stud->submitAll();
ui->add_new_stud->setEnabled(false);
}
Удалить
запись
:
void MainWindow::del_dis()
{
int a=ui->disc_viev->currentIndex().row();
QSqlRecord record1=Disciplina->record(a);
bool k=false,l=false;
for(int i=0;i<Prep_Plan->rowCount();i++)
{
QSqlRecord record2=Prep_Plan->record(i);
if(record1.value("ID_disc").toInt()==record2.value("ID_disc").toInt())
k=true;
}
for(int i=0;i<Inf_Disc->rowCount();i++)
{
QSqlRecord record2=Inf_Disc->record(i);
if(record1.value("ID_disc").toInt()==record2.value("ID_disc").toInt())
l=true;
}
if (k==false&&l==false)
{
Disciplina->removeRow(a);
Disciplina->submitAll();
}
else
{
int r = QMessageBox::question(this, tr("DELETE DISCIPLINE"),
tr("Delete \"%1\" and its links?")
.arg(record1.value("b_disc").toString()),
QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No | QMessageBox::Escape);
if (r == QMessageBox::No)
return;
else
{
for(int i=0;i<Prep_Plan->rowCount();i++)
{
QSqlRecord record2=Prep_Plan->record(i);
if(record1.value("ID_disc").toInt()==record2.value("ID_disc").toInt())
{
Prep_Plan->removeRow(i);
Prep_Plan->submitAll();
}
}
for(int i=0;i<Inf_Disc->rowCount();i++)
{
QSqlRecord record2=Inf_Disc->record(i);
if(record1.value("ID_disc").toInt()==record2.value("ID_disc").toInt())
{
Inf_Disc->removeRow(i);
Inf_Disc->submitAll();
}
}
Disciplina->removeRow(a);
Disciplina->submitAll();
}
}
}
void MainWindow::del_prep()
{
int a=ui->prep_viev->currentIndex().row();
QSqlRecord record1=Prepodavatel->record(a);
bool k=false;
for(int i=0;i<Inf_Disc->rowCount();i++)
{
QSqlRecord record2=Inf_Disc->record(i);
if(record1.value("ID_prep").toInt()==record2.value("ID_prep").toInt())
k=true;
}
if (k==false)
{
Prepodavatel->removeRow(a);
Prepodavatel->submitAll();
}
else
{
int r = QMessageBox::question(this, tr("DELETE PREPOD"),
tr("Delete \"%1\" and its links?")
.arg(record1.value("b_prep").toString()),
QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No | QMessageBox::Escape);
if (r == QMessageBox::No)
return;
else
{
for(int i=0;i<Inf_Disc->rowCount();i++)
{
QSqlRecord record2=Inf_Disc->record(i);
if(record1.value("ID_prep").toInt()==record2.value("ID_prep").toInt())
{
Inf_Disc->removeRow(i);
Inf_Disc->submitAll();
}
}
Prepodavatel->removeRow(a);
Prepodavatel->submitAll();
}
}
}
void MainWindow::del_plan()
{
int a=ui->plan_viev->currentIndex().row();
QSqlRecord record1=Plan->record(a);
bool k=false,l=false;
for(int i=0;i<Prep_Plan->rowCount();i++)
{
QSqlRecord record2=Prep_Plan->record(i);
if(record1.value("ID_plan").toInt()==record2.value("ID_plan").toInt())
k=true;
}
for(int i=0;i<Inf_Stud->rowCount();i++)
{
QSqlRecord record2=Inf_Stud->record(i);
if(record1.value("ID_plan").toInt()==record2.value("ID_plan").toInt())
l=true;
}
if (k==false&&l==false)
{
Plan->removeRow(a);
Plan->submitAll();
}
else
{
int r = QMessageBox::question(this, tr("DELETE PLAN"),
tr("Delete \"%1\" and its links?")
.arg(record1.value("b_plan").toString()),
QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No | QMessageBox::Escape);
if (r == QMessageBox::No)
return;
else
{
for(int i=0;i<Prep_Plan->rowCount();i++)
{
QSqlRecord record2=Prep_Plan->record(i);
if(record1.value("ID_plan").toInt()==record2.value("ID_plan"))
{
Prep_Plan->removeRow(i);
Prep_Plan->submitAll();
}
}
for(int i=0;i<Inf_Stud->rowCount();i++)
{
QSqlRecord record2=Inf_Stud->record(i);
if(record1.value("ID_plan").toInt()==record2.value("ID_plan").toInt())
{
Inf_Stud->removeRow(i);
Inf_Stud->submitAll();
}
}
Plan->removeRow(a);
Plan->submitAll();
}
}
}
void MainWindow::del_stud()
{
int a=ui->stud_viev->currentIndex().row();
QSqlRecord record1=Student->record(a);
bool k=false;
for(int i=0;i<Inf_Stud->rowCount();i++)
{
QSqlRecord record2=Inf_Stud->record(i);
if(record1.value("ID_stud").toInt()==record2.value("ID_stud").toInt())
k=true;
}
if (k==false)
{
Student->removeRow(a);
Student->submitAll();
}
else
{
int r = QMessageBox::question(this, tr("DELETE STUENT"),
tr("Delete \"%1\" and its links?")
.arg(record1.value("b_stud").toString()),
QMessageBox::Yes | QMessageBox::Default,
QMessageBox::No | QMessageBox::Escape);
if (r == QMessageBox::No)
return;
else
{
for(int i=0;i<Inf_Stud->rowCount();i++)
{
QSqlRecord record2=Inf_Stud->record(i);
if(record1.value("ID_stud").toInt()==record2.value("ID_stud").toInt())
{
Inf_Stud->removeRow(i);
Inf_Stud->submitAll();
}
}
Student->removeRow(a);
Student->submitAll();
}
}
}
void MainWindow::del_nagruz()
{
int a=ui->nagruz_viev_2->currentIndex().row();
QSqlRecord record1=model1.record(a);
int b=ui->plan_viev->currentIndex().row();
QSqlRecord record2=Plan->record(b);
model1.setQuery(tr("DELETE FROM Prep_Plan WHERE (ID_disc IN (SELECT ID_disc FROM Disciplina WHERE b_disc=\"%1\")) AND (ID_plan IN (SELECT ID_plan FROM Plan WHERE b_plan=\"%2\")) AND kurs=\"%3\"").arg(record1.value("b_disc").toString()).arg(record2.value("b_plan").toString()).arg(record1.value("kurs").toString()));
model1.setQuery(tr("SELECT b_disc,kurs,lec,labs,prakt,zach,exam FROM Disciplina, Plan, Prep_Plan WHERE Disciplina.ID_disc=Prep_Plan.ID_disc AND Prep_Plan.ID_plan=Plan.ID_plan AND (b_plan=\"%1\") AND (year_plan=\"%2\") AND (year_prod=\"%3\")").arg(record2.value("b_plan").toString()).arg(record2.value("year_plan").toInt()).arg(record2.value("year_prod").toInt()));
ui->nagruz_viev_2->setModel(&model1);
}
void MainWindow::del_new_stud()
{
int a=ui->listView->currentIndex().row();
int n=ui->plan_viev->currentIndex().row();
QSqlRecord record1=Plan->record(n);
QSqlRecord record2=model11.record(a);
model33.setQuery(tr("DELETE FROM Inf_Stud WHERE (ID_stud IN (SELECT ID_stud FROM Student WHERE b_stud=\"%1\")) AND (ID_plan IN (SELECT ID_plan FROM Plan WHERE b_plan=\"%2\"))").arg(record2.value("b_stud").toString()).arg(record1.value("b_plan").toString()));
model11.setQuery(tr("SELECT b_stud FROM Student, Inf_Stud, Plan WHERE (Student.ID_stud=Inf_Stud.ID_stud) AND (Inf_Stud.ID_plan=Plan.ID_plan) AND (b_plan=\"%1\") AND (year_plan=\"%2\") AND (year_prod=\"%3\")").arg(record1.value("b_plan").toString()).arg(record1.value("year_plan").toInt()).arg(record1.value("year_prod").toInt()));
ui->listView->setModel(&model11);
ui->del_new_stud->setEnabled(false);
Inf_Stud->submitAll();
}
Применить
:
void MainWindow::ok_disc()
{
Disciplina->submitAll();
ui->disc_viev->resizeColumnsToContents();
model44.setQuery("SELECT b_disc,b_prep FROM Prepodavatel, Disciplina, Inf_Disc WHERE Prepodavatel.ID_prep=Inf_Disc.ID_prep AND Inf_Disc.ID_disc=Disciplina.ID_disc");
ui->tableView_2->setModel(&model44);
if(c==true){
int a=ui->plan_viev->currentIndex().row();
QSqlRecord record1=Plan->record(a);
model1.setQuery(tr("SELECT b_disc,kurs,lec,labs,prakt,zach,exam FROM Disciplina, Plan, Prep_Plan WHERE Disciplina.ID_disc=Prep_Plan.ID_disc AND Prep_Plan.ID_plan=Plan.ID_plan AND (b_plan=\"%1\") AND (year_plan=\"%2\") AND (year_prod=\"%3\")").arg(record1.value("b_plan").toString()).arg(record1.value("year_plan").toInt()).arg(record1.value("year_prod").toInt()));
ui->nagruz_viev_2->setModel(&model1);}
}
void MainWindow::ok_prep()
{
Prepodavatel->submitAll();
ui->prep_viev->resizeColumnsToContents();
model44.setQuery("SELECT b_disc,b_prep FROM Prepodavatel, Disciplina, Inf_Disc WHERE Prepodavatel.ID_prep=Inf_Disc.ID_prep AND Inf_Disc.ID_disc=Disciplina.ID_disc");
ui->tableView_2->setModel(&model44);
}
void MainWindow::ok_plan()
{
bool k=false;
QSqlRecord record0=Plan->record(Plan->rowCount()-1);
for(int i=0;i<Plan->rowCount()-1;i++)
{
QSqlRecord record1=Plan->record(i);
if(record1.value("b_plan").toString()==record0.value("b_plan").toString()&&record1.value("year_plan").toInt()==record0.value("year_plan").toInt()&&record1.value("year_prod").toInt()==record0.value("year_prod").toInt())
k=true;
}
if(k==true)
{
QMessageBox::information(this, tr("DUBL"),
tr("This plan is already in the table"));
Plan->revertAll();
}
else
Plan->submitAll();
}
void MainWindow::ok_stud()
{
Student->submitAll();
if(c==true){
int a=ui->plan_viev->currentIndex().row();
QSqlRecord record1=Plan->record(a);
model11.setQuery(tr("SELECT b_stud FROM Student, Inf_Stud, Plan WHERE (Student.ID_stud=Inf_Stud.ID_stud) AND (Inf_Stud.ID_plan=Plan.ID_plan) AND (b_plan=\"%1\") AND (year_plan=\"%2\") AND (year_prod=\"%3\")").arg(record1.value("b_plan").toString()).arg(record1.value("year_plan").toInt()).arg(record1.value("year_prod").toInt()));
ui->listView->setModel(&model11);}
}
Отменить
:
void MainWindow::can_plan()
{
Plan->revertAll();
}
void MainWindow::can_stud()
{
Student->revertAll();
}
Изменить
:
void MainWindow::ok_nagruz()
{
int a=ui->nagruz_viev_2->currentIndex().row();
QSqlRecord record1=model1.record(a);
int b=ui->plan_viev->currentIndex().row();
QSqlRecord record2=Plan->record(b);
idplan=record2.value("ID_plan").toInt(); //
сохранили
код
изменяемого
плана
idkurs=record1.value("kurs").toInt();
model55.setQuery(tr("SELECT ID_disc FROM Disciplina WHERE (b_disc=\"%1\")").arg(record1.value("b_disc").toString()));
record1=model55.record(0);
iddisc=record1.value("ID_disc").toInt();
izmenitnagr form;
form.exec();
model1.setQuery(tr("SELECT b_disc,kurs,lec,labs,prakt,zach,exam FROM Disciplina, Plan, Prep_Plan WHERE Disciplina.ID_disc=Prep_Plan.ID_disc AND Prep_Plan.ID_plan=Plan.ID_plan AND (b_plan=\"%1\") AND (year_plan=\"%2\") AND (year_prod=\"%3\")").arg(record2.value("b_plan").toString()).arg(record2.value("year_plan").toInt()).arg(record2.value("year_prod").toInt()));
ui->nagruz_viev_2->setModel(&model1);
}
Обновить
:
void MainWindow::Refresh()
{
QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery("SELECT b_disc,b_stud,c_stud,b_prep,b_plan,year_plan,year_prod,kurs,lec, labs, prakt, zach, exam FROM Disciplina,Student,Prepodavatel,Plan,Prep_Plan,Inf_Stud,Inf_Disc WHERE (Disciplina.ID_disc=Inf_Disc.ID_disc) AND (Prepodavatel.ID_prep=Inf_Disc.ID_prep) AND (Inf_Stud.ID_stud=Student.ID_stud) AND (Plan.ID_plan=Inf_Stud.ID_plan) AND (Prep_Plan.ID_disc=Disciplina.ID_disc) AND (Prep_Plan.ID_plan=Plan.ID_plan)");
ui->tableView->setModel(model);
QSqlQuery q("select distinct b_stud from Student");
int i=0; QString str;
ui->comboBox_2->clear();
while(q.next())
{
str=q.value(0).toString();
ui->comboBox_2->addItem(str,i);
i++;
}}
Генерировать
отчёт
:
void MainWindow::Report()
{
QString k,y;
k=ui->comboBox_2->currentText();
QSqlQuery query;
query.exec("delete from tmp");
query.prepare("INSERT INTO tmp (b_stud, year_plan)"
"VALUES (:id1, :id2)");
query.bindValue(":id1",k);
query.bindValue(":id2",y);
query.exec();
rep_int=dynamic_cast<Report::ReportInterface*>(rep_eng.loadReport("myReport.bdrt"));
rep_int->setDatabase(db);
rep_int->exec();
}
Отображение нагрузки и студентов по нажатию на учебный план:
void MainWindow::plan_and_students()
{
f=true; c=true;
ui->ok_nagruz->setEnabled(false);
ui->del_new_stud->setEnabled(false);
ui->add_nagr->setEnabled(true);
ui->del_nagruz->setEnabled(false);
int a=ui->plan_viev->currentIndex().row();
QSqlRecord record1=Plan->record(a);
model11.setQuery(tr("SELECT b_stud FROM Student, Inf_Stud, Plan WHERE (Student.ID_stud=Inf_Stud.ID_stud) AND (Inf_Stud.ID_plan=Plan.ID_plan) AND (b_plan=\"%1\") AND (year_plan=\"%2\") AND (year_prod=\"%3\")").arg(record1.value("b_plan").toString()).arg(record1.value("year_plan").toInt()).arg(record1.value("year_prod").toInt()));
ui->listView->setModel(&model11);
model1.setQuery(tr("SELECT b_disc,kurs,lec,labs,prakt,zach,exam FROM Disciplina, Plan, Prep_Plan WHERE Disciplina.ID_disc=Prep_Plan.ID_disc AND Prep_Plan.ID_plan=Plan.ID_plan AND (b_plan=\"%1\") AND (year_plan=\"%2\") AND (year_prod=\"%3\")").arg(record1.value("b_plan").toString()).arg(record1.value("year_plan").toInt()).arg(record1.value("year_prod").toInt()));
ui->nagruz_viev_2->setModel(&model1);
QString str=record1.value("b_plan").toString();
int d=record1.value("ID_plan").toInt();
QSqlQuery query;
query.exec("delete from tmp");
query.prepare("INSERT INTO tmp (b_stud, year_plan)"
"VALUES (:id1, :id2)");
query.bindValue(":id1",str);
query.bindValue(":id2",d);
query.exec();
}
Функции обеспечения ограничений целостности (сокрытие кнопок):
void MainWindow::st()
{
ui->del_new_stud->setEnabled(true);
}
void MainWindow::st_viev()
{
if(f==true)
ui->add_new_stud->setEnabled(true);
ui->del_new_stud->setEnabled(false);
int a=ui->stud_viev->currentIndex().row();
QSqlRecord record1=Student->record(a);
bool k=false;
for(int i=0;i<Inf_Stud->rowCount();i++)
{
QSqlRecord record2=Inf_Stud->record(i);
if(record1.value("ID_stud").toInt()==record2.value("ID_stud").toInt())
k=true;
}
if (k==true)
{
ui->add_new_stud->setEnabled(false);
}
}
void MainWindow::izm_nag()
{
ui->ok_nagruz->setEnabled(true);
ui->del_nagruz->setEnabled(true);
}
Для неосновного класса add_d
isc
(добавить дисциплину):
Отображение
таблиц
:
Disciplina=new QSqlTableModel(0,db);
Disciplina->setTable("Disciplina");
Disciplina->select();
Сигналы
:
QObject::connect(m_ui->add, SIGNAL(clicked()),this, SLOT(add()));
Добавить
дисциплину
:
void add_disc::add()
{
QString str=m_ui->lineEdit->text();
bool k=false;
for(int i=0;i<Disciplina->rowCount();i++)
{
QSqlRecord record1=Disciplina->record(i);
if(record1.value("b_disc").toString()==str)
k=true;
}
if(k==true)
{
QMessageBox::information(this, tr("DUBL"),
tr("This discipline is already in the table"));
}
else {
QSqlQuery query;
query.prepare("INSERT INTO Disciplina (b_disc)"
"VALUES (:id2)");
query.bindValue(":id2",str);
query.exec();
add
_
disc
::
close
();
}
}
Для неосновного класса add_
nagruz
(связь Дисциплина-План):
Отображение
таблиц
:
Prep_Plan=new QSqlTableModel(0,db);
Prep_Plan->setTable("Prep_Plan");
Prep
_
Plan
->
select
();
Вывод в комбо бокс преподавателей:
QString str;
QSqlQuery q("select distinct b_disc from Disciplina"); //вывод в комбо боксы преподавателей
int i=0;
while(q.next())
{
str=q.value(0).toString();
m_ui->_prep->addItem(str,i);
i++;
Сигналы
:
QObject::connect(m_ui->add1, SIGNAL(clicked()),this, SLOT(add1()));
Добавить
нагрузку
:
void add_nagruz::add1()
{
Qt::CheckState state_1, state_2;
int zach, exam;
state_1 = m_ui->checkBox->checkState();
state_2 = m_ui->checkBox_2->checkState();
if ( state_1 == Qt::Checked ) {zach=1;}
else {zach=0;}
if ( state_2 == Qt::Checked ) {exam=1;}
else {exam=0;}
int kurs, lec, labs, prakt;
kurs=m_ui->spinBox->value();
lec=m_ui->spinBox_2->value();
labs=m_ui->spinBox_3->value();
prakt=m_ui->spinBox_4->value();
QString k,s;
k=m_ui->_prep->currentText();
model1.setQuery("SELECT ID_disc FROM Disciplina WHERE b_disc='"+k+"'");
QSqlRecord record3=model1.record(0);
int prep=record3.value("ID_disc").toInt();
model1.setQuery("SELECT year_plan FROM tmp");
record3=model1.record(0);
int plan=record3.value("year_plan").toInt();
bool d=false;
for(int i=0;i<Prep_Plan->rowCount();i++)
{
QSqlRecord record2=Prep_Plan->record(i);
if(record2.value("ID_disc").toInt()==prep&&record2.value("ID_plan").toInt()==plan&&record2.value("kurs").toInt()==kurs)
d=true;
}
if(d==true){
QMessageBox::information(this, tr("DUBL"),
tr("This plan is already in the table"));
}
else
{
QSqlQuery query;
query.prepare("INSERT INTO Prep_Plan (ID_disc, ID_plan, kurs, lec, labs, prakt, zach, exam)"
"VALUES (:id1, :id2, :kurs, :lec, :labs, :prakt, :zach, :exam)");
query.bindValue(":id1",prep);
query.bindValue(":id2",plan);
query.bindValue(":kurs",kurs);
query.bindValue(":lec",lec);
query.bindValue(":labs",labs);
query.bindValue(":prakt",prakt);
query.bindValue(":zach",zach);
query.bindValue(":exam",exam);
query.exec();
}
}
Для неосновного класса add_
prep
(добавить преподавателя):
Отображение
таблиц
:
Prepodavatel=new QSqlTableModel(0,db);
Prepodavatel->setTable("Prepodavatel");
Prepodavatel->select();
Сигналы
:
QObject::connect(m_ui->add, SIGNAL(clicked()),this, SLOT(add()));
Добавить преподавателя:
void add_prepod::add()
{
QString str=m_ui->lineEdit->text();
QSqlQuery query;
query.prepare("INSERT INTO Prepodavatel (b_prep)"
"VALUES (:id2)");
query.bindValue(":id2",str);
query.exec();
add_prepod::close();
}
Для неосновного класса
dis
_
prep
(Дисциплина-Преподаватель):
Отображение
таблиц
:
model1.setQuery("SELECT b_disc FROM Disciplina");
model2.setQuery("SELECT b_prep FROM Prepodavatel");
model3.setQuery("SELECT b_disc,b_prep FROM Prepodavatel, Disciplina, Inf_Disc WHERE Prepodavatel.ID_prep=Inf_Disc.ID_prep AND Inf_Disc.ID_disc=Disciplina.ID_disc");
m_ui->listView_1->setModel(&model1);
m_ui->listView_2->setModel(&model2);
m_ui->tableView->setModel(&model3);
Inf_Disc=new QSqlTableModel(0,db);
Inf_Disc->setTable("Inf_Disc");
Inf_Disc->select();
Сигналы
:
QObject::connect(m_ui->add3, SIGNAL(clicked()),this, SLOT(add3()));
QObject::connect(m_ui->del, SIGNAL(clicked()),this, SLOT(del()));
QObject::connect(m_ui->tableView,SIGNAL(clicked(QModelIndex)),this,SLOT(disc_and_prepod()));
QObject::connect(m_ui->listView_1,SIGNAL(clicked(QModelIndex)),this,SLOT(disc()));
QObject::connect(m_ui->listView_2,SIGNAL(clicked(QModelIndex)),this,SLOT(prepod()));
m_ui->del->setEnabled(false);
m_ui->add3->setEnabled(false);
Добавление связи Дисциплина-Преподаватель:
void
dis
_
prep
::
add
3()
{
int a=m_ui->listView_1->currentIndex().row(); //
номер
строки
дисциплины
QSqlRecord record1=model1.record(a); //
записываем
в
record1
имя
дисциплины
с
этой
строки
int b=m_ui->listView_2->currentIndex().row(); //
номер
строки
препода
QSqlRecord record2=model2.record(b); //
записываем
в
record2
имя
препода
с
этой
строки
bool k=false;
for(int i=0;i<Inf_Disc->rowCount();i++)
{
QSqlRecord record3=model3.record(i);
if(record1.value("b_disc").toString()==record3.value("b_disc").toString())
k=true;
}
if(k==true)
{
QMessageBox::information(this, tr("DUBL"),
tr("This discipline is already in the table"));
}
else
{
model3.setQuery(tr("INSERT INTO Inf_Disc (ID_disc,ID_prep) SELECT ID_disc, ID_prep FROM Disciplina, Prepodavatel WHERE (Disciplina.b_disc=\"%1\") AND (Prepodavatel.b_prep=\"%2\")").arg(record1.value("b_disc").toString()).arg(record2.value("b_prep").toString()));
model3.setQuery("SELECT b_disc,b_prep FROM Prepodavatel, Disciplina, Inf_Disc WHERE Prepodavatel.ID_prep=Inf_Disc.ID_prep AND Inf_Disc.ID_disc=Disciplina.ID_disc");
m_ui->tableView->setModel(&model3);
}}
Удаление
связи
:
void dis_prep::del()
{
int a=m_ui->tableView->currentIndex().row();
QSqlRecord record1=model3.record(a);
model3.setQuery(tr("DELETE FROM Inf_Disc WHERE ID_disc IN (SELECT ID_prep FROM Prepodavatel WHERE b_prep=\"%1\")").arg(record1.value("b_prep").toString()));
model3.setQuery("SELECT b_disc,b_prep FROM Prepodavatel, Disciplina, Inf_Disc WHERE Prepodavatel.ID_prep=Inf_Disc.ID_prep AND Inf_Disc.ID_disc=Disciplina.ID_disc");
m_ui->tableView->setModel(&model3);
m_ui->del->setEnabled(false);
}
Активность
/
пассивность
кнопок
:
void dis_prep::disc_and_prepod()
{
m_ui->del->setEnabled(true);
}
void dis_prep::disc()
{
a=true;
if(a&&b) m_ui->add3->setEnabled(true);
}
void dis_prep::prepod()
{
b=true;
if(a&&b) m_ui->add3->setEnabled(true);
}
Для неосновного класса
izmenitnagr
(Изменение выбранной нагрузки):
Отображение
таблиц
:
Prep_Plan=new QSqlTableModel(0,db);
Prep_Plan->setTable("Prep_Plan");
Prep_Plan->select();
Отображение
дисциплин
в
ComboBox:
QString str;
QSqlQuery query;
query.prepare("select distinct b_disc from Disciplina where ID_disc=:id1");
query.bindValue(":id1",iddisc);
query.exec();
int i=0;
while(query.next())
{str=query.value(0).toString();
m_ui->_prep->addItem(str,i);
i++;}
query.prepare("select distinct b_disc from Disciplina no where ID_disc!=:id1");
query.bindValue(":id1",iddisc);
query.exec();
i=0;
while(query.next())
{str=query.value(0).toString();
m_ui->_prep->addItem(str,i);
i++;}
Отображение исходных значений в spinBox:
m_ui->spinBox->setValue(idkurs);
m_ui->spinBox_3->setValue(iddisc);
model1.setQuery(tr("SELECT lec,labs,prakt,zach,exam FROM Prep_Plan WHERE (ID_plan=\"%1\") AND (ID_disc=\"%2\") AND (kurs=\"%3\")").arg(idplan).arg(iddisc).arg(idkurs));
QSqlRecord record1=model1.record(0);
m_ui->spinBox_2->setValue(record1.value("lec").toInt());
m_ui->spinBox_3->setValue(record1.value("labs").toInt());
m_ui->spinBox_4->setValue(record1.value("prakt").toInt());
Сигналы
:
QObject::connect(m_ui->add1, SIGNAL(clicked()),this, SLOT(add1()));
Изменение записи:
void izmenitnagr::add1()
{
Qt::CheckState state_1, state_2;
int zach, exam;
state_1 = m_ui->checkBox->checkState();
state_2 = m_ui->checkBox_2->checkState();
if ( state_1 == Qt::Checked ) {zach=1;}
else {zach=0;}
if ( state_2 == Qt::Checked ) {exam=1;}
else {exam=0;}
int kurs, lec, labs, prakt; kurs=m_ui->spinBox->value();
lec=m_ui->spinBox_2->value();
labs=m_ui->spinBox_3->value();
prakt=m_ui->spinBox_4->value();
QString k;
k=m_ui->_prep->currentText();
model1.setQuery(tr("SELECT ID_disc FROM Disciplina WHERE (b_disc=\"%1\")").arg(k));
QSqlRecord record1=model1.record(0);
model2.setQuery(tr("SELECT ID_disc, ID_plan, kurs,lec,labs,prakt,zach,exam FROM Prep_Plan WHERE (ID_plan=\"%1\") AND (ID_disc=\"%2\") AND (kurs=\"%3\")").arg(idplan).arg(iddisc).arg(idkurs));
model1.setQuery(tr("DELETE FROM Prep_Plan WHERE (ID_plan=\"%1\") AND (ID_disc=\"%2\") AND (kurs=\"%3\")").arg(idplan).arg(iddisc).arg(idkurs));
Prep_Plan->select();
QSqlRecord record3=model2.record(0);
bool d=false;
for(int i=0;i<Prep_Plan->rowCount();i++)
{QSqlRecord record2=Prep_Plan->record(i);
if(record2.value("ID_disc").toInt()==record1.value("ID_disc").toInt()&&record2.value("ID_plan").toInt()==idplan&&record2.value("kurs").toInt()==kurs)
d=true;}
if(d==true)
{QMessageBox::information(this, tr("DUBL"),
tr("This plan is already in the table"));
QSqlQuery query;
query.prepare("INSERT INTO Prep_Plan (ID_disc, ID_plan, kurs, lec, labs, prakt, zach, exam)"
"VALUES (:id1, :id2, :kurs, :lec, :labs, :prakt, :zach, :exam)");
query.bindValue(":id1",record3.value("ID_disc").toInt());
query.bindValue(":id2",record3.value("ID_plan").toInt());
query.bindValue(":kurs",record3.value("kurs").toInt());
query.bindValue(":lec",record3.value("lec").toInt());
query.bindValue(":labs",record3.value("labs").toInt());
query.bindValue(":prakt",record3.value("prakt").toInt());
query.bindValue(":zach",record3.value("zach").toInt());
query.bindValue(":exam",record3.value("exam").toInt());
query.exec();}
else{
QSqlQuery query;
query.prepare("INSERT INTO Prep_Plan (ID_disc, ID_plan, kurs, lec, labs, prakt, zach, exam)"
"VALUES (:id1, :id2, :kurs, :lec, :labs, :prakt, :zach, :exam)");
query.bindValue(":id1",record1.value("ID_disc").toInt());
query.bindValue(":id2",idplan);
query.bindValue(":kurs",kurs);
query.bindValue(":lec",lec);
query.bindValue(":labs",labs);
query.bindValue(":prakt",prakt);
query.bindValue(":zach",zach);
query.bindValue(":exam",exam);
query.exec();}}
Классы, их методы и поля
Основной класс:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
QSqlQueryModel model1,model11, model3, model33, model44, model55 ;
private:
Ui::MainWindow *ui;
Report::ReportEngine rep_eng;
Report::ReportInterface* rep_int;
QSqlDatabase db;
QSqlTableModel *Disciplina;
QSqlTableModel *Student;
QSqlTableModel *Prepodavatel;
QSqlTableModel *Plan;
QSqlTableModel *Prep_Plan;
QSqlTableModel *Inf_Stud;
QSqlTableModel *Inf_Disc;
QSqlQueryModel *model2;
private slots:
void add_dis(); void add_prep(); void add_plan(); void add_stud();
void del_dis(); void del_prep(); void del_plan(); void del_stud();
void ok_disc(); void ok_prep(); void ok_plan(); void ok_stud();
void can_plan(); void can_stud();
void add_nagr(); void disc_prep(); void plan_and_students();
void del_nagruz(); void Refresh(); void add_new_stud();
void ok_nagruz(); void Report(); void del_new_stud();
void st();
void st_viev();
void izm_nag();
};
Класс
add_disc (
добавить
дисциплину
):
class add_disc : public QDialog {
Q_OBJECT
public:
add_disc(QWidget *parent = 0);
~add_disc();
protected:
void changeEvent(QEvent *e);
private:
Ui::add_disc *m_ui;
QSqlDatabase db;
QSqlTableModel *Disciplina;
private slots:
void
add
();
};
Класс add_
nagruz
(добавить связь Дисциплина-План):
class add_nagruz : public QDialog {
Q_OBJECT
public:
add_nagruz(QWidget *parent = 0);
~add_nagruz();
QSqlQueryModel model1,model2;
//QSqlTableModel *Prep_Plan;
protected:
void changeEvent(QEvent *e);
private:
Ui::add_nagruz *m_ui;
QSqlDatabase db;
QCheckBox *checkBox,*checkBox_2;
QTextEdit *textEdit,*textEdit_2;
QSqlTableModel *Prep_Plan,*tmp;
private slots:
void add1();
};
Класс
add_prepod (
Добавить
преподавателя
):
class add_prepod : public QDialog {
Q_OBJECT
public:
add_prepod(QWidget *parent = 0);
~add_prepod();
protected:
void changeEvent(QEvent *e);
private:
Ui::add_prepod *m_ui;
QSqlDatabase db;
QSqlTableModel *Prepodavatel;
private slots:
void
add();
};
Класс dis_prep (добавить связь Дисциплина-Преподаватель):
class dis_prep : public QDialog {
Q_OBJECT
public:
dis_prep(QWidget *parent = 0);
~dis_prep();
QSqlQueryModel model1, model2, model3, model4 ;
protected:
void changeEvent(QEvent *e);
private:
Ui::dis_prep *m_ui;
QSqlDatabase db;
QSqlTableModel *Prepodavatel,*Disciplina,*Inf_Disc;
private slots:
void disc(); void prepod(); void disc_and_prepod(); void add3(); void del();
};
Класс izmenitnagr (Изменить связь Дисциплина-План):
class izmenitnagr : public QDialog {
Q_OBJECT
public:
izmenitnagr(QWidget *parent = 0);
~izmenitnagr();
QSqlQueryModel model1,model2;
protected:
void changeEvent(QEvent *e);
private:
Ui::izmenitnagr *m_ui;
QSqlDatabase db;
QCheckBox *checkBox,*checkBox_2;
QTextEdit *textEdit,*textEdit_2;
QSqlTableModel Disciplina,*Prep_Plan,*tmp;
private slots:
void add1();
};
Процедуры и функции по реализации ограничений целостности, включая SQL запросы
1) Не может быть больше одной дисциплины с одинаковым названием.
При попытке добавления дисциплины, уже имеющейся в базе данных, или при изменении названия существующей дисциплины на уже имеющееся, выскакивает сообщение о невозможности данного действия. Листинг представлен на странице 19.
2) Не может быть двух и более одинаковых учебных планов. При попытке добавления учебного плана, уже имеющейся в базе данных, или при изменении существующего плана на уже имеющееся, выскакивает сообщение о невозможности данного действия. Листинг представлен на странице 15.
3) Не может быть удалён студент, для которого определён учебный план. При удалении студента необходимо удалять связанные поля в таблице «Студент-План». При удалении студента, имеющего связи с планами, выскакивает диалог об удалении связей. При нажатии «ДА» удаляются студент и его связи. Листинг представлен на странице 13.
4) При удалении дисциплины необходимо удалять также связанные поля в таблице «Дисциплина-Преподаватель» и «Дисциплина-План. При удалении дисциплины, имеющей связи, выскакивает диалог об удалении связей. При нажатии «ДА» удаляется дисциплина и её связи. Листинг представлен на странице 10.
5) При удалении учебного плана необходимо также удалять связанные поля в таблице «Дисциплина-План» и «Студент-План». При удалении плана, имеющего связи, выскакивает диалог об удалении связей. При нажатии «ДА» удаляется план и его связи. Листинг представлен на странице 12.
6) При удалении преподавателя необходимо также удалять связанные поля в таблице «Дисциплина-Преподаватель». При удалении преподавателя, имеющего связи, выскакивает диалог об удалении связей. При нажатии «ДА» удаляется преподаватель и его связи. Листинг представлен на странице 11.
7) Нельзя добавлять связи для несуществующих студентов, преподавателей, планов и дисциплин. Это ОЦ реализовано с помощью ограничения пользователя в выборе параметров только из справочников.
SQL запросы по созданию таблиц:
CREATE TABLE Disciplina (ID_DISC INTEGER PRIMARY KEY, b_disc VARCHAR(20));
CREATE TABLE Student (ID_stud INTEGER PRIMARY KEY, b_stud VARCHAR(30), c_stud VARCHAR(5));
CREATE TABLE Prepodavatel (ID_PREP INTEGER PRIMARY KEY, b_prep VARCHAR(30));
CREATE TABLE Plan (ID_plan INTEGER PRIMARY KEY, b_plan VARCHAR(30), year_plan INTEGER, year_prod INTEGER);
CREATE TABLE Prep_Plan (ID_disc INTEGER, ID_plan INTEGER, kurs INTEGER, lec INTEGER, labs INTEGER, prakt INTEGER, zach INTEGER, exam INTEGER, PRIMARY KEY(ID_disc,ID_plan,kurs));
CREATE TABLE Inf_Stud (ID_stud INTEGER, ID_plan INTEGER, PRIMARY KEY(ID_stud));
CREATE TABLE Inf_Disc (ID_disc INTEGER, ID_prep INTEGER, PRIMARY KEY(ID_disc));
CREATE TABLE tmp (b_stud VARCHAR(30), year_plan INTEGER PRIMARY KEY);
SQL запросы по ведению электронного аналога документа
В приложении пользователю предоставляется выбор, по какому студенту сформировать отчёт.
При генерации отчёта выполняется запись выбранной ФИО студента в таблицу tmp. После этого вызывается отчёт, в котором с помощью простого запроса отображается значение полей, относящихся к выбранному студенту. Такой метод позволяет изменять содержимое отчёта в зависимости от конкретных требований. Далее представлен листинг.
Листинг
в
eXaro:
SELECT Disciplina.b_disc,Student.b_stud,c_stud,b_prep,b_plan,Plan.year_plan,year_prod,kurs,lec, labs, prakt, zach, exam FROM Disciplina,Student,Prepodavatel,Plan,Prep_Plan,Inf_Stud,Inf_Disc,tmp WHERE (Disciplina.ID_disc=Inf_Disc.ID_disc) AND (Prepodavatel.ID_prep=Inf_Disc.ID_prep) AND (Inf_Stud.ID_stud=Student.ID_stud) AND (Plan.ID_plan=Inf_Stud.ID_plan) AND (Prep_Plan.ID_disc=Disciplina.ID_disc) AND (Prep_Plan.ID_plan=Plan.ID_plan)AND (tmp.b_stud=Student.b_stud);
Листинг в
Qt
:
QString k,y;
k=ui->comboBox_2->currentText();
QSqlQuery query;
query.exec("delete from tmp");
query.prepare("INSERT INTO tmp (b_stud, year_plan)"
"VALUES (:id1, :id2)");
query.bindValue(":id1",k);
query.bindValue(":id2",y);
query.exec();
Описание
экранных
форм
1) В первой, второй, третьей и четвёртой экранной форме добавляются и редактируются дисциплины и преподаватели, при этом не может быть добавлены дисциплины с одинаковыми названиями. Также из формы 1 может быть вызвана форма удаления/добавления связи Дисциплина-Преподаватель, при этом нельзя добавить существующую связь (см. приложение 1,2,3,4). При удалении дисциплины или преподавателя, имеющих связи, появляются диалоги (приложение 5). При добавлении существующей связи Дисциплина-Преподаватель появляется диалог (приложение 6).
2) Во пятой форме добавляются учебные планы и студенты, при этом нельзя добавить два и более одинаковых плана (приложение 7). При удалении связанных объектов выскакивает диалог подобный приложению 5. Также здесь отображается список студентов, учащихся по выбранному плану, и нагрузка по предметам на этот план. Ограничение целостности на удаление/добавление студента в таблицу связи Студент-План осуществляется путём разрешения/запрещения пользователю нажимать соответствующие кнопки. Из этой формы можно вызвать формы добавления нового учебного плана нажатием кнопки «Новый план» (приложение 8) и изменения существующего нажатием кнопки «Изменить» (приложение 9).
3) В следующей экранной форме отображается вся база данных целиком и здесь же можно выбрать критерий формирования отчёта и получить его в виде, удобном для просмотра и печати (приложение 10).
4) При нажатии на кнопку «Сгенерировать отчёт» выводится отчёт по выбранному студенту в виде, удобном для сохранения, печати и просмотра (приложение 11).
Руководство по эксплуатации
1) При внесении информации в приложение используются 7 таблиц: дисциплины, преподаватели, учебные планы, студенты, связь дисциплина-преподаватель, связь студент-план, связь дисциплина-план.
2) При внесении информации в таблицу «Дисциплины» необходимо учитывать то, что название дисциплины не может повторяться. А при удалении происходит удаление не только самих дисциплин, но и всех их связей». То же самое относится и к таблицам «Студенты», «Преподаватели», «Учебные планы».
3) Для добавления связи дисциплина-преподаватель необходимо нажать кнопку «Дисциплина-Преподаватель» во вкладке главного окна «Дисциплины и преподаватели». В появившемся окне (приложение 4) необходимо выбрать дисциплину и преподавателя из соответствующих списков, после чего станет активной кнопка «Добавить». Для удаления нужно выбрать удаляемую строку и нажать на кнопку «Удалить».
4) При добавлении записей в таблицы связей нет необходимости следить, чтобы не добавить запись для несуществующих объектов, т.к. выбор добавляемых объектов осуществляется только из описанных в справочниках. При удалении связи важно помнить, что разрывается связь между дисциплинами, преподавателями, студентами или планами.
5) Для того чтобы добавлять записи в таблицы связь студент-план и связь дисциплина-план, необходимо выбрать учебный план, с которым будет производиться дальнейшая работа. После данного действия в соответствующих окнах отобразится вся информация по этому плану, а именно список студентов и нагрузка. Чтобы внести изменения в нагрузку учебного плана, необходимо сначала выбрать план, затем выбрать предмет, для которого нужно изменить нагрузку. После этого кнопка «Изменить» станет активной.
6) Кнопка «Добавить студента» в таблицу связи «студент-план» (зелёная стрелка, направленная влево) активна только если выделен учебный план, добавляемый студент и если для этого студента ещё не назначено плана. Кнопка «Удалить студента» из таблицы связи «студент-план» (зелёная стрелка, направленная вправо) доступна если выбрать учебный план и студента, который к нему относится.
7) Таблица «Отчёт» дана для учёта данных, в ней невозможно изменять информацию. В приложении, также реализована возможность выбора студента для формирования отчёта. Кнопка «обновить» служит для обновления таблицы после внесения изменений в базу данных. Кнопка «генерировать отчёт» предназначена для формирования отчёта в зависимости от выбранного студента.
Заключение
В ходе проделанной работы были получены навыки программирования на QT, а также создания простых приложений. Ознакомился с основными запросами SQLite и принципами ведения простейшей базы данных. Были получены навыки формирования отчётов с помощью генератора EXARO. Результатом работы явилось, функциональное и удобное для пользователя приложение, которое может использоваться для работы с учебными планами.
Список использованной литературы
1) Qt4. Профессиональное программирование на C++. – СПб.: БХВ-Петербург, 2007. – 880 с: ил.+ CD-ROM – (В подлиннике)
2) Введение в системы баз данных, 7-е издание. : Пер. с англ. – М. : Издательский дом “Вильямс”, 2001. – 1072 с. : ил. – Парал. тит. англ.
3) Qt4. Программирование GUI на С++.:Ж.Бланшет, М.Саммерфилд.: КУДИЦ-ПРЕСС Москва, 2007. – 641с
Приложение
Приложение 1
Приложение 2
Приложение 3
Приложение 4
Приложение 5
Приложение 6
Приложение 7
Приложение 8
Приложение 9
Приложение 10
Приложение 11