#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
#include
#include
#include
char situation_1[] = {1,1,1,1,1};
char situation_2[] = {2,1,1,2,2};
char situation_3[] = {2,2,2,2,2};
char situation_4[] = {3,2,3,3,2};
char situation_5[] = {3,3,3,3,3};
//********************* подсказка оператору ***********************
QString situationInfo[5];
int readSqlSetting(dbSettingMySql *setting)
{
QFile fileSetting("config.cfg");
QTextStream fileStream(&fileSetting);
if(!fileSetting.open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox::critical(NULL, "Ошибка", "Не удалось открыть файл настроек");
return ERR_CRITICAL;;
}
// пропуск строки коментария
fileStream.readLine();
//чтение строки настроек
strcpy_s(setting->host, 128, fileStream.readLine().toLocal8Bit().data());
fileStream.readLine();
// пропуск строки коментария
fileStream.readLine();
//чтение строки настроек
strcpy_s(setting->login, 128, fileStream.readLine().toLocal8Bit().data());
fileStream.readLine();
// пропуск строки коментария
fileStream.readLine();
//чтение строки настроек
strcpy_s(setting->password, 128, fileStream.readLine().toLocal8Bit().data());
fileStream.readLine();
// пропуск строки коментария
fileStream.readLine();
//чтение строки настроек
strcpy_s(setting->nameDB, 128, fileStream.readLine().toLocal8Bit().data());
fileStream.readLine();
// пропуск строки коментария
fileStream.readLine();
//чтение строки настроек
strcpy_s(setting->nameTablClients, 128, fileStream.readLine().toLocal8Bit().data());
fileStream.readLine();
// пропуск строки коментария
fileStream.readLine();
//чтение строки настроек
strcpy_s(setting->nameTablCLientsData, 128, fileStream.readLine().toLocal8Bit().data());
fileStream.readLine();
// пропуск строки коментария
fileStream.readLine();
//чтение строки настроек
strcpy_s(setting->nameTablVariantAccessRight, 128, fileStream.readLine().toLocal8Bit().data());
//закрытие файла
fileSetting.close();
return 0;
}
int writeSqlSetting(dbSettingMySql setting)
{
QFile fileSetting("config.cfg");
QTextStream fileStream(&fileSetting);
if(!fileSetting.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
{
QMessageBox::critical(NULL, "Ошибка", "Не удалось открыть файл настроек");
return ERR_CRITICAL;;
}
// запись строки коментария
fileStream << "#host" << endl;
//запись строки настроек
fileStream << setting.host << endl;
fileStream << endl;
// запись строки коментария
fileStream << "#login" << endl;
//запись строки настроек
fileStream << setting.login << endl;
fileStream << endl;
// запись строки коментария
fileStream << "#password" << endl;
//запись строки настроек
fileStream << setting.password << endl;
fileStream << endl;
// запись строки коментария
fileStream << "#nameDB" << endl;
//запись строки настроек
fileStream << setting.nameDB << endl;
fileStream << endl;
// запись строки коментария
fileStream << "#nameTablClients" << endl;
//запись строки настроек
fileStream << setting.nameTablClients << endl;
fileStream << endl;
// запись строки коментария
fileStream << "#nameTablCLientsData" << endl;
//запись строки настроек
fileStream << setting.nameTablCLientsData << endl;
fileStream << endl;
// запись строки коментария
fileStream << "#nameTablVariantAccessRight" << endl;
//запись строки настроек
fileStream << setting.nameTablVariantAccessRight << endl;
fileStream << endl;
//закрытие файла
fileSetting.close();
return 0;
}
int dbSqlStart(dbSettingMySql *setting)
{
/*
if(setting->MySqlConnectDB == NULL)
{
QMessageBox::critical(NULL, "Ошибка", "Не удалось создать SQL подключение");
return ERR_CRITICAL;
}
*/
if(!mysql_real_connect(setting->MySqlConnectDB, setting->host, setting->login, setting->password, setting->nameDB, NULL, NULL, 0))
{
// Если нет возможности установить соединение с сервером
// базы данных выводим сообщение об ошибке
QMessageBox::critical(NULL, "Ошибка", "Сервер или база данных не доступны");
return ERR_CONNECT;
}
//результат запроса
MYSQL_RES *res;
//строка
//MYSQL_ROW row;
// Проверка существования таблицы
QString query("show tables like '");
query += QString(setting->nameTablClients) + "'";
if (mysql_query(setting->MySqlConnectDB, query.toLocal8Bit().data()))
{
QMessageBox::critical(NULL, "Ошибка", mysql_error(setting->MySqlConnectDB));
}
res = mysql_store_result(setting->MySqlConnectDB);
int colRow = (int)mysql_num_rows(res);
std::cerr << "\ncount: " << colRow << endl;
if(colRow < 1)
{
QString tmp("Табица \"");
tmp += QString(setting->nameTablClients);
tmp += QString("\" недоступна, проверьте имена таблиц");
QMessageBox::critical(NULL, "Ошибка", tmp );
return ERR_CRITICAL;
}
// Проверка существования таблицы
query = "show tables like '";
query += QString(setting->nameTablCLientsData) + "'";
if (mysql_query(setting->MySqlConnectDB, query.toLocal8Bit().data()))
{
QMessageBox::critical(NULL, "Ошибка", mysql_error(setting->MySqlConnectDB));
}
res = mysql_store_result(setting->MySqlConnectDB);
colRow = (int)mysql_num_rows(res);
std::cerr << "\ncount: " << colRow << endl;
if(colRow < 1)
{
QString tmp("Табица \"");
tmp += QString(setting->nameTablCLientsData);
tmp += QString("\" недоступна, проверьте имена таблиц");
QMessageBox::critical(NULL, "Ошибка", tmp );
return ERR_CRITICAL;
}
//установка русской кодировки
//mysql_query(setting->MySqlConnectDB, "SET NAMES 'utf8'");
//mysql_query(setting->MySqlConnectDB, "SET CHARACTER SET 'utf8'");
mysql_query(setting->MySqlConnectDB, "SET NAMES 'cp1251'");
mysql_query(setting->MySqlConnectDB, "SET CHARACTER SET 'cp1251'");
return 0; //OK
}
int computeSituation(userDataForSituation dataSituation, char *situationCoeff)
{
QDate res;
//******** время регистрации в системе *************************************
res.fromJulianDay(QDate::currentDate().toJulianDay() - dataSituation.dateReg.toJulianDay());
if(res.year() > 1)
{
situationCoeff[0] = 3;
}
else if(res.month() < 1)
{
situationCoeff[0] = 1;
}
else
{
situationCoeff[0] = 2;
}
//******** судимость *************************************
if(dataSituation.conviction == 0)
{
situationCoeff[1] = 3;
}
else if(dataSituation.conviction == 1)
{
situationCoeff[1] = 2;
}
else if(dataSituation.conviction == 2)
{
situationCoeff[1] = 1;
}
else
{
-1;
}
//******** время работы на последнем месте *************************************
if(dataSituation.dateWorking.isNull())
{
res.fromJulianDay(QDate::currentDate().toJulianDay() - dataSituation.dateWorking.toJulianDay());
if(res.year() > 3)
{
situationCoeff[2] = 3;
}
else if(res.year() < 3)
{
situationCoeff[2] = 2;
}
else
{
-1;
}
}
else
{
situationCoeff[3] = 1;
}
//******** возраст *************************************
res.fromJulianDay(QDate::currentDate().toJulianDay() - dataSituation.dateBurstDay.toJulianDay());
if(res.year() < 18 || res.year() > 70)
{
situationCoeff[3] = 1;
}
else if(res.year() < 25 || res.year() > 60)
{
situationCoeff[3] = 2;
}
else
{
situationCoeff[3] = 3;
}
//******** годовой доход т.р. *************************************
if(dataSituation.annualIncome >= 500)
{
situationCoeff[4] = 3;
}
else if(dataSituation.annualIncome < 200)
{
situationCoeff[4] = 1;
}
else
{
situationCoeff[4] = 2;
}
return 0;
}
int getCoef(userDataForSituation dataSituation)
{
char coeff[5];
computeSituation(dataSituation, coeff);
std::cerr << "coeff " << (int)coeff[0] << (int)coeff[1] << (int)coeff[2] << (int)coeff[3] << (int)coeff[4] << "\n";
float distance1 = sqrt(pow((float)situation_1[0]-(float)coeff[0], 2) + pow((float)situation_1[1]-(float)coeff[1], 2) + \
pow((float)situation_1[2]-(float)coeff[2], 2) + pow((float)situation_1[3]-(float)coeff[3], 2) + \
pow((float)situation_1[4]-(float)coeff[4], 2));
float distance2 = sqrt(pow((float)situation_2[0]-(float)coeff[0], 2) + pow((float)situation_2[1]-(float)coeff[1], 2) + \
pow((float)situation_2[2]-(float)coeff[2], 2) + pow((float)situation_2[3]-(float)coeff[3], 2) + \
pow((float)situation_2[4]-(float)coeff[4], 2));
float distance3 = sqrt(pow((float)situation_3[0]-(float)coeff[0], 2) + pow((float)situation_3[1]-(float)coeff[1], 2) + \
pow((float)situation_3[2]-(float)coeff[2], 2) + pow((float)situation_3[3]-(float)coeff[3], 2) + \
pow((float)situation_3[4]-(float)coeff[4], 2));
float distance4 = sqrt(pow((float)situation_4[0]-(float)coeff[0], 2) + pow((float)situation_4[1]-(float)coeff[1], 2) + \
pow((float)situation_4[2]-(float)coeff[2], 2) + pow((float)situation_4[3]-(float)coeff[3], 2) + \
pow((float)situation_4[4]-(float)coeff[4], 2));
float distance5 = sqrt(pow((float)situation_5[0]-(float)coeff[0], 2) + pow((float)situation_5[1]-(float)coeff[1], 2) + \
pow((float)situation_5[2]-(float)coeff[2], 2) + pow((float)situation_5[3]-(float)coeff[3], 2) + \
pow((float)situation_5[4]-(float)coeff[4], 2));
float resDistance = 100000; //заведомо максимальное значение
int coef;
if(resDistance > distance1){ resDistance = distance1; coef = 1; }
if(resDistance > distance2){ resDistance = distance2; coef = 2; }
if(resDistance > distance3){ resDistance = distance3; coef = 3; }
if(resDistance > distance4){ resDistance = distance4; coef = 4; }
if(resDistance > distance5){ resDistance = distance5; coef = 5; }
return coef;
}
//************************* AppLogic.c****************************
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Устанвка свойств первой таблицы
model = new QStandardItemModel(0,5,this);
model->setHorizontalHeaderItem(0, new QStandardItem(QString("Номер\nучастника")));
model->setHorizontalHeaderItem(1, new QStandardItem(QString("Псевдоним")));
model->setHorizontalHeaderItem(2, new QStandardItem(QString("Номер\nтелефона")));
model->setHorizontalHeaderItem(3, new QStandardItem(QString("Электронная\nпочта")));
model->setHorizontalHeaderItem(4, new QStandardItem(QString("Коэффициент\nдоверия")));
ui->tableView->setModel(model);
ui->tableView->horizontalHeader()->setStretchLastSection(true);
ui->tableView->verticalHeader()->setDefaultSectionSize(20);
ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
//ui->tableView->setEnabled(false);
// Установка свойств второй таблицы
model2 = new QStandardItemModel(0,2,this);
ui->tableView_2->setModel(model2);
ui->tableView_2->horizontalHeader()->setStretchLastSection(true);
ui->tableView_2->verticalHeader()->setDefaultSectionSize(20);
model2->setHorizontalHeaderItem(0, new QStandardItem(QString("Поле")));
model2->setHorizontalHeaderItem(1, new QStandardItem(QString("Данные")));
ui->tableView_2->horizontalHeader()->setDefaultSectionSize(200);
//ui->tableView_2->setEnabled(false);
/*
model.setHorizontalHeaderLabels(
QStringList() << QApplication::translate("nestedlayouts", "Name")
<< QApplication::translate("nestedlayouts", "Office"));
QList rows = QList()
<< (QStringList() << "Verne Nilsen" << "123")
<< (QStringList() << "Carlos Tang" << "77")
<< (QStringList() << "Bronwyn Hawcroft" << "119")
<< (QStringList() << "Alessandro Hanssen" << "32")
<< (QStringList() << "Andrew John Bakken" << "54")
<< (QStringList() << "Vanessa Weatherley" << "85")
<< (QStringList() << "Rebecca Dickens" << "17")
<< (QStringList() << "David Bradley" << "42")
<< (QStringList() << "Knut Walters" << "25")
<< (QStringList() << "Andrea Jones" << "34");
foreach(QStringList row, rows)
{
QList items;
foreach (QString text, row)
items.append(new QStandardItem(text));
model.appendRow(items);
} */
//****************Настройка базы данных*******************************
//инициализация структуры
mysql_init(&dbConectMySql);
//сохранение адреса dbConectMySql в настройки
dbSetting.MySqlConnectDB = &dbConectMySql;
//загрузка настроек из файла
readSqlSetting(&dbSetting);
//функция проверки доступности БД
dbSqlStart(&dbSetting);
memoListTable.append(QString("Номер в базе"));
memoListTable.append(QString("Фамилия"));
memoListTable.append(QString("Имя"));
memoListTable.append(QString("Отчество"));
memoListTable.append(QString("Дата рождения"));
memoListTable.append(QString("Место рождения"));
memoListTable.append(QString("Номер паспорта"));
memoListTable.append(QString("Дата выдачи паспорта"));
memoListTable.append(QString("Место выдачи паспорта"));
memoListTable.append(QString("Судимость"));
memoListTable.append(QString("Адрес места работы"));
memoListTable.append(QString("Годовой доход т.р."));
memoListTable.append(QString("Степень доверия"));
memoListTable.append(QString("Предоставление кредита"));
memoListTable.append(QString("Покупки в магазинах"));
memoListTable.append(QString("Банковские операции"));
memoListTable.append(QString("Размер предоставляемого кредита"));
situationInfo[4] = "Полное доверие = {3,3,3,3,3}\n"
"- может брать/давать кредит\n"
"- может оплачивать интернет услуги\n"
"- может выводить средства\n"
"- лимит 10000 $";
situationInfo[3] = "Достаточное доверие = {3,2,3,3,2}\n"
"- не может брать/давать кредит\n"
"- может оплачивать интернет услуги\n"
"- может выводить средства\n"
"- лимит 5000 $";
situationInfo[2] = "Средний уровень доверия = {2,2,2,2,2}\n"
"- не может брать/давать кредит\n"
"- может оплачивать интернет услуги\n"
"- может выводить средства\n"
"- лимит 1000$ долларов";
situationInfo[1] = "Низкий уровень доверия = {2,1,1,2,2}\n"
"- не может брать/давать кредит\n"
"- может оплачивать интернет услуги\n"
"- может выводить средства\n"
"- лимит 500 баксов";
situationInfo[0] = "Отсутствие доверия = {1,1,1,1,1}\n"
"- не может брать/давать кредит\n"
"- может оплачивать интернет услуги\n"
"- не может выводить средства\n"
"- лимит 0";
}
MainWindow::~MainWindow()
{
delete ui;
delete model;
delete model2;
mysql_close(&dbConectMySql);
memoListTable.clear();
}
// ПОИСК В БД
void MainWindow::on_commandLinkButton_pressed()
{
QString query("select idclients, login, tel, email, accessRights from clients join clientsData on clients.idclients = clientsdata.idclient ");
MYSQL_RES *res;
MYSQL_ROW row;
int isWheare = 0;
QString search;
//Фамилия
if(ui->lineEdit->text().length() > 2)
{
if(isWheare) {search.append(",");}
isWheare = 1;
search.append(" family = \"" + ui->lineEdit->text() + "\"");
}
else if(ui->lineEdit_2->text().length() > 2)
{
if(isWheare) {search.append(",");}
isWheare = 1;
search.append(" name = \"" + ui->lineEdit_2->text() + "\"");
}
else if(ui->lineEdit_3->text().length() > 2)
{
if(isWheare) {search.append(",");}
isWheare = 1;
search.append(" lastName = \"" + ui->lineEdit_3->text() + "\"");
}
else if(ui->lineEdit_4->text().length() > 2)
{
if(isWheare) {search.append(",");}
isWheare = 1;
search.append(" passportNum = \"" + ui->lineEdit_4->text() + "\"");
}
else if(ui->lineEdit_5->text().length() > 2)
{
if(isWheare) {search.append(",");}
isWheare = 1;
search.append(" email = \"" + ui->lineEdit_5->text() + "\"");
}
else if(ui->comboBox->currentIndex() > 0)
{
if(isWheare) {search.append(",");}
isWheare = 1;
search.append(" accessRights = \"" + QString::number(ui->comboBox->currentIndex()) + "\"");
}
// Добавление параметров поиска
if(isWheare)
{
query += " AND " + search;
}
if (mysql_query(&dbConectMySql, query.toLocal8Bit().data()))
{
QMessageBox::critical(NULL, "Ошибка", mysql_error(&dbConectMySql));
}
res = mysql_store_result(&dbConectMySql);
if(mysql_num_rows(res) < 1)
{
std::cerr << "\nSIZE RETURN QUERY1 < 0" << endl;
}
//удаление предыдущего результата
model->clear();
// вывод результата запроса
QList itemsTableTop;
while(row = mysql_fetch_row(res))
{
for (unsigned int i=0 ; i < mysql_num_fields(res); i++)
{
itemsTableTop.append(new QStandardItem(row[i]));
std::cerr<
}
model->appendRow(itemsTableTop);
itemsTableTop.clear();
}
ui->textEdit->setText(query);// return;
return;
}
void MainWindow::on_tableView_pressed(const QModelIndex &index)
{
userDataForSituation DataSituation;
//QModelIndex index;
if(model->rowCount() < 1){ return; }
QString idClientData = model->index(index.row(), 0).data().toString();
//формирование запроса на выборку
QString query("SELECT idclient, family, name, "
"lastName, dateBD, locationBD, passportNum, "
"passportDate, passportEmit, conviction, "
"jobAddress, annualIncome, confidence, giveCredit, PayAtTheStore, "
"banking, giveCreditSumRUR "
"FROM " + QString(dbSetting.nameTablCLientsData) + " join"
" " + QString(dbSetting.nameTablVariantAccessRight) + " ON "
" " + QString(dbSetting.nameTablCLientsData) + ".idClient = \"" + idClientData + \
"\" AND " + QString(dbSetting.nameTablVariantAccessRight) + ".idvariantAccessRight = " \
+ QString(dbSetting.nameTablCLientsData) + ".idCLient" );
ui->textEdit->setText(query);// return;
MYSQL_RES *res;
MYSQL_ROW row;
if (mysql_query(&dbConectMySql, query.toLocal8Bit().data()))
{
QMessageBox::critical(NULL, "Ошибка", mysql_error(&dbConectMySql));
return;
}
res = mysql_store_result(&dbConectMySql);
if(mysql_num_rows(res) < 1)
{
std::cerr << "\nSIZE RETURN QUERY1 < 0" << endl;
}
//удаление предыдущего результата
model2->clear();
// вывод результата запроса
QList itemsTableTop;
QListIterator strDataIter(memoListTable);
while(row = mysql_fetch_row(res))
{
for (unsigned int i=0 ; i < mysql_num_fields(res); i++)
{
switch(i)
{
case 17: //дата регистрации в системе
DataSituation.dateReg = QDate::fromString(QString::fromLocal8Bit( row[i]), Qt::ISODate); // YYYY-MM-DD
break;
case 9: // судимость
DataSituation.conviction = (char)QString::fromLocal8Bit( row[i]).toInt();
break;
case 18: // стаж на последнем месте работы
DataSituation.dateWorking = QDate::fromString(QString::fromLocal8Bit( row[i]), Qt::ISODate); // YYYY-MM-DD
break;
case 4: // возраст
DataSituation.dateBurstDay = QDate::fromString(QString::fromLocal8Bit( row[i]), Qt::ISODate); // YYYY-MM-DD
break;
case 11: // годовой доход
DataSituation.annualIncome = QString::fromLocal8Bit( row[i]).toInt();
break;
default:
break;
}
itemsTableTop.append(new QStandardItem(strDataIter.next()));
if(i < 13 || i > 15)
{
itemsTableTop.append(new QStandardItem(QString::fromLocal8Bit( row[i])));
}
else
{
QString tmp;
if(QString::fromLocal8Bit( row[i]) == "0")
{
tmp = "Нет";
}
else
{
tmp = "Да";
}
itemsTableTop.append(new QStandardItem(tmp));
}
model2->appendRow(itemsTableTop);
itemsTableTop.clear();
}
}
//вычисление степени доверия
int coefUser = getCoef(DataSituation);
model2->setItem(12,2,&QStandardItem(QString::number(coefUser)));
// информация оператору
ui->textEdit_2->setText(situationInfo[coefUser]);
}
int MainWindow::dbDeleteClientData(dbSettingMySql *setting, int idClient)
{
//формирование запроса на выборку
QString query("DELETE FROM " + QString(setting->nameTablClients) + " WHERE "
"idClients = " + QString::number(idClient));
ui->textEdit->setText(query);// return;
QString query2("DELETE FROM " + QString(setting->nameTablCLientsData) + " WHERE "
"idClient = " + QString::number(idClient));
ui->textEdit->setText(query2);// return;
MYSQL_RES *res;
MYSQL_ROW row;
if (mysql_query(&dbConectMySql, query.toLocal8Bit().data()))
{
QMessageBox::critical(NULL, "Ошибка", mysql_error(&dbConectMySql));
return ERR_QUERY;
}
if (mysql_query(&dbConectMySql, query2.toLocal8Bit().data()))
{
QMessageBox::critical(NULL, "Ошибка", mysql_error(&dbConectMySql));
return ERR_QUERY;
}
return 0;
}
void MainWindow::on_tableView_customContextMenuRequested(const QPoint &pos)
{
if(model->rowCount() < 1) { return; }
int selectedRow = ui->tableView->selectionModel()->currentIndex().row();
//numClient - ID выбранного клиента
QString idClientData = model->index(selectedRow, 0).data().toString();
QPushButton *popupButton = new QPushButton/*(tr("Pop&up Button"))*/;
QMenu *menu = new QMenu(this);
menu->addAction("Обновить данные клиента");
menu->insertSeparator(0);
menu->addAction("Удалить данные клиента");
popupButton->setMenu(menu);
QAction* selectedItem;
selectedItem = menu->exec(QCursor::pos());
if(selectedItem == NULL)
{
return;
}
if(selectedItem->text() == "Обновить данные клиента")
{
std::cerr << "0";
return;
}
if(selectedItem->text() == "Удалить данные клиента")
{
std::cerr << "1";
dbDeleteClientData(&dbSetting, idClientData.toInt());
model->removeRow(selectedRow);
return;
}
}
Приложение 3. Графическая часть.
6.Список использованной литературы.
[1] http://knowledge.allbest.ru/bank/2c0b65625a3bd68a4c43a88421306c37_0.html
[2] www.studmed.ru/docs/document24164/реферат-вербальный-анализ-принятия-решений
[3] http://lissianski.narod.ru/dwarch/dwarch.html
[4] http://ru.wikipedia.org/wiki/Метод Дельфи
[5] Системы поддержки принятия решений, конспект лекций МИЭМ
[6] www.rusdoc.ru/articles/elektrodengi--obzor_elektronnyx_platezhnyx_sistem_interneta
[7] Компьютерные технологии в бизнесе, региональный финансово экономический институт, Курск 2011
[8] http://ru.wikipedia.org/wiki/EasyPay
[9] ru.wikipedia.org/wiki/Иерархическая_модель_данных
[10] Информационные системы поддержки принятия управленческих решений. Конспект лекций. - Самара.:ГОУВПО ПГУТИ , 2011
[11] Атанасян Л.С., Бутузов В.Ф., Кадомцев С.Б., Киселева Л.С., Позняк Э.Г. Геометрия. Учебник для 10-11 классов средней школы.
[12] ru.wikipedia.org/wiki/Firebird
[13] www.coolreferat.com/Системы_электронных_платежей_интернета
[14].http://knowledge.allbest.ru/management
[15] Ларичев О.И. Теория и методы принятия решений, а так же хроника событий в Волшебных странах, Логос 2000
[16] ru.wikipedia.org/wiki/База_данных
[17] ru.wikipedia.org/wiki/Объектно-ориентированная_база_данных
[18] ru.wikipedia.org/wiki/Сетевая_модель_данных
[19] ru.wikipedia.org/wiki/Первичный_ключ
[20] ru.wikipedia.org/wiki/Microsoft_Access
[21] ru.wikipedia.org/wiki/MySQL
[22] ru.wikipedia.org/wiki/Microsoft_SQL_Server
Достарыңызбен бөлісу: |