Re[2]: Разница в SQL
От: Sheridan Россия  
Дата: 20.08.09 09:46
Оценка:
Приветствую, Nonmanual Worker, вы писали:

NW> Здравствуйте, Sheridan, Вы писали:


NW> S>Приветствую!

NW> S>Уважаемые, есть ли где-ть собранная воедино инфа про разницу в SQL диалектах разных БД?

NW> Слишком пространная информация вам нужна.

NW> Уточните, какие конкретно СУБД вас интересуют? Разница в чем конкретно — операторы, форма записи идентификаторов\строк? А то, например сравнивая MySQL 4 и Oracle 10, проще сказать что там общего.
Ну пока что postgresql, mysql, firebird и sqlite
С ddl в принципе я разобрался более менее, нужен sql. Пока что интересует вот что:
1. Типы данных bool, varchar, int, date, time, datetime, blob — да, ddl, но в принципе этот пункт неважен пока
2. Маскировка ключевых слов (ну к примеру в мускуле select * from `table` — не выдаст ошибку что мол table — кейворд)
3. Формат записи строк
Ну и прочие мелочи типа ограничения выборки. Может еще что добавите...
Пока что конструкции sql — простые, даже без джойнов.

Для чего:
Рисую для С++ (Qt) так сказать генератор sql под разные БД. Он-же будет и реструктуризатором базы.
Грубо говоря в коде будет чтототипа
CREATE_TABLE(forums);
        APPEND_FIELD(forums, id, T_INTEGER); SET_UNIQUE(forums, id);
        APPEND_FIELD(forums, groupid, T_INTEGER);
        APPEND_FIELD(forums, shortname, T_STRING); SET_MAX_LENGTH(forums, shortname, 128);
        APPEND_FIELD(forums, name, T_STRING);
        APPEND_FIELD(forums, rated, T_BOOL);
        APPEND_FIELD(forums, intop, T_BOOL);
        APPEND_FIELD(forums, ratelimit, T_INTEGER);
        APPEND_FIELD(forums, subscribed, T_BOOL); SET_DEFAULT(forums, subscribed, false);
        SET_PRIMARY_KEY(forums, id);
        APPEND_INDEX_FIELD(forums, id, idAsc);
        APPEND_INDEX_FIELD(forums, groupid, idAsc);
        APPEND_INDEX_FIELDS(forums, TABLE_FIELD(forums, shortname) << TABLE_FIELD(forums, name), idAsc);
//--------------
SELECT(get_forums);
        FIELD(get_forums, forums, name);
        FIELD(get_forums, forums, shortname);
        FIELD(get_forums, forums, id);
    FROM(get_forums, forums);
    WHERE
        VALUE_CONDITION(get_forums, forums, subscribed, C_EQUAL);

это код на дефайнах, который я максимально приближаю к sql синтаксису. Подразумевается что сия штука будет обрабатываться при запуске приложения, реструктуризировать бд если надо и генерировать sql запросы к базе, складывая их в map<имя, запрос>, а далее при работе достаточно будет прикрутить параметры к запросу и отправить на исполнение.
Вот.
Со стороны дб-модуля это выглядит приблизительно так:
void CPostgreEngine::checkDatabases(const db::objmodel::CDBMDatabaseDefinition *db)
{
    db::objmodel::CDBMTable *table;
    db::objmodel::CDBMDBField *field;
    db::objmodel::CDBMIndex *index;
    QString ddl;
    foreach(table, db->getTables())
    {
        logger->Append(tr("Checking table %1").arg(table->getName()));
        if (!itemExists(table->getName()))
        {
            exec("CREATE TABLE " + table->getName() + "();");
        }
        foreach(field, table->getFields())
        {
            if (!itemExists(field->getName(), table->getName(), plugins::base::edbField))
            {
                ddl += "ALTER TABLE " + table->getName() + " ADD COLUMN " + field->getName();
                switch (field->getType())
                {
                    case db::objmodel::ftInteger:    ddl += " integer";                                                    break;
                    case db::objmodel::ftString :    ddl += QString(" varchar(%1)").arg(field->getStringFieldLength());    break;
                    case db::objmodel::ftBlob   :    ddl += " bytea";                                                    break;
                    case db::objmodel::ftBool   :    ddl += " bool";                                                        break;
                }
                if (field->isUnique()) {
                    ddl += " UNIQUE"; }
                if (field->isNotNull()) {
                    ddl += " NOT NULL"; }
                if (field->hasDefaultValue()) {
                    ddl += " DEFAULT '" + field->getDefaultValue().toString() + "'"; }
                exec(ddl + ";");
                ddl.clear();
            }
        }
        if (!itemExists(table->getPrimaryKey()->getName(), table->getName(), plugins::base::edbPrimaryKey))
        {
            exec("ALTER TABLE " + table->getName() + " ADD CONSTRAINT " + table->getPrimaryKey()->getName() + " PRIMARY KEY (" + table->getPrimaryKey()->getFieldsNames(",") + ");");
        }
        foreach(index, table->getIndexes())
        {
            if (!itemExists(index->getName(), table->getName(), plugins::base::edbIndex))
            {
                exec("CREATE INDEX " + index->getName() + " ON " + table->getName() + " (" + index->getFieldsNames(",") + ");");
            }
        }
    }
}
//----------------------------
QString CPostgreEngine::buildSelectQuery(db::objmodel::CDBMQuery *query)
{
    db::objmodel::CDBMQueryField *field;
    QString queryText    = "SELECT ";
    foreach(field, query->getFields())
    {
        switch(field->getSpecialType())
        {
            case db::objmodel::sftNone:    queryText += field->getLinkedField()->getFullName() + ","; break;    // not special, standart field
            case db::objmodel::sftAll:    queryText += "*,"; break;    // *
            case db::objmodel::sftCount:    queryText += QString("count(%1) as %2,").arg(field->getLinkedField()->getFullName()).arg(field->getName()); break;    // count(table.field) as f
            case db::objmodel::sftSumm:    queryText += QString("summ(%1) as %2,").arg(field->getLinkedField()->getFullName()).arg(field->getName()); break;    // summ(table.field) as f
            case db::objmodel::sftMax:    queryText += QString("max(%1) as %2,").arg(field->getLinkedField()->getFullName()).arg(field->getName()); break;    // max(table.field) as f
            case db::objmodel::sftMin:    queryText += QString("min(%1) as %2,").arg(field->getLinkedField()->getFullName()).arg(field->getName()); break;    // min(table.field) as f
            case db::objmodel::sftSimple:    queryText += QString("\"%1\" as %2,").arg(field->getPresetValue()).arg(field->getName()) ; break;    // "text" as f
        }
    }
    queryText.resize(queryText.length() - 1);
    queryText += " FROM " + query->getTablesNames();
    if (!query->conditionsIsEmpty()) {
        queryText += buildConditions(query->getConditions()); }
    return queryText;
}
avalon 1.0rc2 rev 300, zlib 1.2.3
build date: 19.08.2009 14:13:36 MSD +04:00
Qt 4.5.2
Matrix has you...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.