crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в SQLite и хранимые процедуры
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
Теги
Выровнять по центру
Ссылка на тему
Ссылка на сообщение
Скрытый текст
Сокращение
Код с подсветкой
Offtopic
 
Удалить форматирование
Спец. элементы
Шрифт
Размер
 
Цвет шрифта
 
Отменить ввод
Вернуть ввод
Полужирный
Курсив
Подчеркнутый
 
 
Смайлики
Вставить изображение
Вставить адрес электронной почты
Цитата
Код
Раскрывающийся текст
 
Увеличить отступ
По левому краю
По центру
По правому краю
Вставить список
Вставить список

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
Алексей1153 Дата 10.8.2010, 11:54
  пригодится, спасибо ) Прям мануал получился
Iron Bug Дата 10.8.2010, 11:40
  Ради эксперимента написала тестовую реализацию только через стандартный sqlite3 интерфейс.
Если кому интересно, то вот:

Раскрывающийся текст
#include <iostream>

#include <sqlite3.h>

using namespace std;

// вызываемая функция
void foo(sqlite3_context* context,int argc,sqlite3_value** argv)
{
  if(argc!=1)
  {
      sqlite3_result_error_code(context,-1);
      return;
  }
  switch( sqlite3_value_type(argv[0]) )
  {
    case SQLITE_INTEGER: {
      long long int iVal = sqlite3_value_int64(argv[0]);
      // пускай будет умножение на десять
      iVal *= 10;

      sqlite3_result_int64(context, iVal);
      break;
    }
    default: {
      sqlite3_result_null(context);
      break;
    }
  }
}

int main()
{
    sqlite3 *db;
    char *zErrMsg = 0;
    int rc;

    // создали базу
    rc = sqlite3_open("SQLiteTestDB",&db);
    if( rc ){
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        exit(1);
    }
    // создание тестовой таблицы
    rc = sqlite3_exec(db,"create table TEST(id int)",0,0,&zErrMsg);
    if( rc!=SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    }

    // создание функции
    rc = sqlite3_create_function(db,"FOO",1,SQLITE_ANY,0, foo, 0,0);
    if( rc!=SQLITE_OK ){
        fprintf(stderr, "SQL error: could not create function\n");
    }

    // положим в базу какие-то данные
    rc = sqlite3_exec(db,"insert into TEST (id) values (1)",0,0,&zErrMsg);
    if( rc!=SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    }
    rc = sqlite3_exec(db,"insert into TEST (id) values (2)",0,0,&zErrMsg);
    if( rc!=SQLITE_OK ){
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    }

    // вычитаем данные
    char **result;
    int nrow,ncol;
    rc = sqlite3_get_table(db,"select id,FOO(id) from TEST",
              &result,&nrow,&ncol,&zErrMsg);

       if( rc == SQLITE_OK ){
            // заголовки
            for(int i=0; i < ncol; ++i)
                cout << result[i] << "\t";
            cout << endl;
            // данные
            for(int i=1; i < nrow; ++i)
            {
                for(int j=0; j < ncol; ++j)
                {
                    if(result[i*ncol+j] != 0)
                    {
                        cout << result[i*ncol+j] << "\t";
                    }
                    else
                    {
                        cout << "NULL" << "\t";
                    }
                }
                cout << endl;
            }
       }
       sqlite3_free_table(result);

    // закрыли базу
    sqlite3_close(db);
    return 0;
}
Iron Bug Дата 10.8.2010, 6:50
  Вот, добралась до работы.

В сишном интерфейсе SQLite есть подгружаемые SQL функции.

В общем, рекомендую посмотреть вот это для информации:
http://www.sqlite.org/c3ref/create_function.html

Далее, используется примерно так:

// база
wxSQLite3Database* pdb;
.....
// объявляем объект новой функции funcLog
SQLite3DBFunc funcLog(LogErrorCheck);
// (по сути, этот объект нигде не используется и нужен только для связи имени в запросе с функцией-обработчиком)
.....
// после открытия базы
pdb->CreateFunction(_T("LOG_ERROR_CHECK"),3,funcLog);
// в параметрах:
// имя функции для запроса, количество параметров и объект регистрируемой функции 
....
// функция-обработчик
void LogErrorCheck(wxSQLite3FunctionContext& context)
{
// проверяем параметры функции
         if(context.GetInt(/*[номер параметра]*/)==/*[какое-то значение]*/)    
         {
                // например, возвращаем NULL
        context.SetResultNull();
         }
        else 
        {
               // например, возвращаем какое-то число
    context.SetResult(/*[какое-то значение]*/);    
        }
}

пример вызова созданной функции в запросе:
// например, так:
select LOG_ERROR_CHECK(STATE,PLD_FUNCTION,PLD_VERSION) as ERROR from LOG
// тут STATE, PLD_FUNCTION,PLD_VERSION - поля таблицы, как обычно в запросах с функциями


При выполнении запроса на каждую запись будет вызвана функция LogErrorCheck и значение, возвращаемое через context.SetResult будет подставлено вместо тега ERROR.

P.S. у меня использован wxSQLite, но с обычным SQLite то же самое будет. просто вызовы маленько по-другому будут оформляться.
Iron Bug Дата 9.8.2010, 18:52
  я завтра посмотрю на работе, как я это реализовывала. тут дома у меня нет кода.
суть в том, что там можно организовать вызов сишной процедуры. регистрируются входы и символические имена и при запросах можно обращаться к ним, как к хранимым процедурам.
ну а так, SQLite - оперсорц, там всё возможно.
DEADHUNT Дата 9.8.2010, 17:58
 
Цитата(legat @ 9.8.2010, 18:03) *
Если нет, то какими способами этот недостаток можно обойти?

написать на C++ аналог нужной хранимой процедуры.
legat Дата 9.8.2010, 17:03
  Поддерживает ли SQLite хранимые процедуры?
Если да, то как средствами Qt их вызвать?
Если нет, то какими способами этот недостаток можно обойти?
Просмотр темы полностью (откроется в новом окне)
RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 9.7.2025, 20:54