Russian Qt Forum

Qt => Кладовая готовых решений => Тема начата: interv от Май 31, 2012, 13:13



Название: [РЕШЕНО] 4 функции для работы с MSSQL (StoredProcedure, Insert, Update, Delete)
Отправлено: interv от Май 31, 2012, 13:13
Столкнулся с проблеммой вызова хранимки с использованием переменных, на форуме инфу чейта не нашел, в результате написал функцию
Еще добавил некоторые функции облегчающие жизнь
Код
C++ (Qt)
const QSqlQuery SQLStoredExecute(const QSqlDatabase &database,
                                const QString &storedFunct,
                                const QMap<QString, QVariant> &variables = QMap<QString, QVariant>())
{
 QSqlQuery stored(database);
 if (variables.isEmpty())
   stored.prepare(storedFunct);
 else
   stored.prepare(QString("{CALL %1(?%2)}")
            .arg(storedFunct)
            .arg(QString(", ?").repeated(variables.size()-1)));
 for (QMap<QString, QVariant>::const_iterator i = variables.constBegin();
      i!=variables.constEnd(); ++i)
   stored.bindValue(i.key(), i.value());
 stored.exec();
 return stored;
}
 
int SQLInsert(const QSqlDatabase &database,
             const QString &table,
             const QMap<QString, QVariant>&variables)
{
 if (variables.isEmpty()) return -1;
 QStringList columns = variables.keys();
 QString queryStr =
     QString("INSERT INTO %1 (%2) VALUES (:%3) SELECT @@IDENTITY")
         .arg(table)
         .arg(columns.join(", "))
         .arg(columns.join(", :"));
 QSqlQuery query(m_Connect);
 query.prepare(queryStr);
 for (QMap<QString, QVariant>::const_iterator i = variables.constBegin(); i!=variables.constEnd(); ++i)
   query.bindValue(i.key(), i.value());
 if (query.exec())
 {
   if (query.next())
     return query.value(0).toInt();
   return 0;
 }
 return -1;
}
 
bool SQLUpdate(const QSqlDatabase &database,
              const QString &table,
              const int &id,
              const QMap<QString, QVariant> &variables)
{
 if (variables.isEmpty()) return false;
 QStringList columns = variables.keys();
 for (int i=0; i<columns.size(); ++i)
   columns[i] = QString("%1=:%1").arg(columns.at(i));
 QString queryStr =
     QString("UPDATE %1 SET %2 WHERE id = %3")
         .arg(table)
         .arg(columns.join(", "))
         .arg(id);
 QSqlQuery query(database);
 query.prepare(queryStr);
 for (QMap<QString, QVariant>::const_iterator i = variables.constBegin(); i!=variables.constEnd(); ++i)
   query.bindValue(i.key(), i.value());
 return query.exec();
}
 
bool SQLDelete(const QSqlDatabase &database,
              const QString &table,
              const int &id)
{
 QSqlQuery query(database);
 QString set = QString("DELETE FROM %1 WHERE id = %2").arg(table).arg(id);
 return query.exec(set);
}
 
const QSqlQuery SQLStoredExecute(const QString &connectionName,
                                const QString &storedFunct,
                                const QMap<QString, QVariant> &variables = QMap<QString, QVariant>())
{
 return SQLStoredExecute(QSqlDatabase::database(connectionName), storedFunct, variables);
}
 
int SQLInsert(const QString &connectionName,
             const QString &table,
             const QMap<QString, QVariant>&variables)
{
 return SQLInsert(QSqlDatabase::database(connectionName), table, variables);
}
 
bool SQLUpdate(const QString &connectionName,
              const QString &table,
              const int &id,
              const QMap<QString, QVariant> &variables)
{
 return SQLUpdate(QSqlDatabase::database(connectionName), table, id, variables);
}
 
bool SQLDelete(const QString &connectionName,
              const QString &table,
              const int &id)
{
 return SQLDelete(QSqlDatabase::database(connectionName), table, id);
}
 
в общем кому интересно - пользуйтесь


Название: Re: StoredProcedure + MSSql(ODBC3) + переменные [Решено]
Отправлено: Пантер от Май 31, 2012, 13:26
QObject::tr зачем?


Название: Re: [РЕШЕНО] StoredProcedure + MSSql(ODBC3) + переменные
Отправлено: interv от Май 31, 2012, 13:40
Если Вы имеете ввиду зачем QObject::, то дело в том, что функция может находиться вне класса QObject и тогда tr будет вне зоне видимости
Если Вы имеете ввиду зачем tr(), то впринципе QObject::tr(***) можно заменить на QString(***) что одно и тоже, только tr мне роднее как-то ))


Название: Re: [РЕШЕНО] StoredProcedure + MSSql(ODBC3) + переменные
Отправлено: Пантер от Май 31, 2012, 13:41
tr используется для локализации, так что в этом случае он абсолютно не нужен. Используй QString.


Название: Re: [РЕШЕНО] StoredProcedure + MSSql(ODBC3) + переменные
Отправлено: interv от Май 31, 2012, 13:52
исправлено


Название: Re: [РЕШЕНО] StoredProcedure + MSSql(ODBC3) + переменные
Отправлено: Пантер от Май 31, 2012, 13:54
1. variables.size()>0 замени на !variables.isEmpty ().
2. Вместо while используй for.
3. Пусть функция принимает имя соединения.


Название: Re: [РЕШЕНО] StoredProcedure + MSSql(ODBC3) + переменные
Отправлено: interv от Май 31, 2012, 14:26
исправил + добавил DefaultValue


Название: Re: [РЕШЕНО] StoredProcedure + MSSql(ODBC3) + переменные
Отправлено: Пантер от Май 31, 2012, 14:31
Ок. Норм.
const QSqlDatabase &database
замени лучше на
const QString &connectionName = QString ()
И юзай http://doc-snapshot.qt-project.org/4.8/qsqldatabase.html#database


Название: Re: [РЕШЕНО] StoredProcedure + MSSql(ODBC3) + переменные
Отправлено: interv от Май 31, 2012, 14:33
Ну это как вариань дублирующей функции, у меня в программе храниться подключение.
Хотя можно рассмотреть как аналог.


Название: Re: [РЕШЕНО] 4 функции для работы с MSSQL (StoredProcedure, Insert, Update, Delete)
Отправлено: interv от Май 31, 2012, 15:55
Понеслось написал еще 3 функции для лучшей жизни


Название: Re: [РЕШЕНО] 4 функции для работы с MSSQL (StoredProcedure, Insert, Update, Delete)
Отправлено: KrupaKarlo от Декабрь 17, 2012, 10:33
Цитировать
QString("INSERT INTO %1 (%2) VALUES (:%3) SELECT @@IDENTITY")

Данный код не точен. У меня с ним были проблемы. Если в бд есть триггеры которые что-то делают по INSERT то SELECT @@IDENTITY может возвращать совершенно другое значение. И вообще тут получается 2 запроса. кто-то может вставить новую запись пока ты делаешь SELECT и получишь не правильный id.

лучше такой вариант для MSSQL

Код:
declare @t table(id_col int); INSERT INTO %1 (%2) OUTPUT INSERTED.id into @t  VALUES (:%3); select * from @t

Во временную переменную записываются результаты запроса. И селектишь именно результат выполненного INSERT