Проблема с кодировкой в БД Paradox

Тема в разделе "Borland C++ Builder & Kylix", создана пользователем SVAN, 6 фев 2006.

Статус темы:
Закрыта.
  1. SVAN

    SVAN Гость

    Господа, возникла следующая проблема:

    имеется некоторое приложение которое работает с двумя БД (базы соответственно в PARADOX) через BDE, назовем их A_DB и B_DB, с помошью компонента TBatchMove переношу данные из таблицы aTable, которая находится в базе A_DB в таблицу bTable, которая находится в базе B_DB (таблицы имеют одинаковую структуру). При копировании используется функция следующего вида

    Код (Text):
    bool TDDataModule::copyRecordInArchive(const AnsiString &aliasName, TDataSet *jDS, TJournals j)
    {
    if (!jDS)
     return false;
    if (j == NJournals::JdscCS)
     TabArchive->TableName = "JdscCS";
    else
     if (j == NJournals::Jesmc)
     TabArchive->TableName = "Jesmc";
     else
     return;
    TabArchive->DatabaseName = aliasName;
    BMArchive->Mode = batCopy;
    BMArchive->Source = dynamic_cast<TBDEDataSet *>(jDS);
    if (!BMArchive->Source)
     return;
    BMArchive->Destination = TabArchive;
    try
     {BMArchive->Execute();}
    catch(...)
     {return false}
    return true;
    }
    Все работает нормально, кроме того что все данные, хранящиеся в таблице aTable в виде строк из русскоязычных символов, например "Объект" переносятся в таблицу bTable в виде "######". С латинскими символами все нормально.
    Пробовал вместо TBatchMove использовать оператор INSERT вида

    Код (Text):
    INSERT INTO ":aliasB_DB:bTable" (Id, Name, Object)
    SELECT (Id, Name, Object) FROM ":aliasA_DB:aTable"
    таже самая ситуация.
    Кто сталкивался, подскажите что можно сделать, чтобы избавиться от проблемы с кодировками.
     
  2. DITR

    DITR Гость

    Попробуйте использовать ADO или ODBC - там свои внутренние перекодировщики есть или используйте промежуточный буфер для декодирования из codepage 866 -> 1251 и назад

    //(codepage 866 -> 1251)
    CString CPlaschadkaDlg::WINConvert( CString m_strDescr )
    {unsigned char ch, chVal;

    for ( int i=0; i<m_strDescr.GetLength(); i++ )
    {chVal = (unsigned char)m_strDescr.GetAt(i);

    if(chVal == 44)
    m_strDescr.SetAt(i, 46);

    if ( chVal >= 128 && chVal <= 159 )
    m_strDescr.SetAt(i, chVal + 64 );// += 64;
    if ( chVal >= 160 && chVal <= 175 )
    m_strDescr.SetAt(i, chVal + 64);// += 64;
    if ( chVal >= 224 && chVal <= 239 )
    m_strDescr.SetAt(i, chVal + 16);// += 16;
    }

    return m_strDescr;
    }
    или
     
  3. Guest

    Guest Гость

    Спасибо за совет, надо будет попробовать копировать данные из одной таблицы в другую, используя ADO. Проблему с кодировками я решил следующим образом: У класса TTable есть метод
    Код (Text):
    InsertRecord(const System::TVarRec * Values, const int Values_Size),
    наследуемый от TDataSet. В качестве параметра передаем ему запись, взятую из набора данных, который нужно скопировать (если интересно, можно посмотреть документацию к TDataSet в Builder). Как ни странно, все нормально работает и никаких проблем с кодировками не возникает.
     
  4. DITR

    DITR Гость

    Так для работы с любой базой данных я использую ADO - принцип работы - на мой взгляд - очень прост. Приведу код на VC++

    Код (Text):
    //В stdafx.h
    //полный путь к msado15.dll на диске у меня в data каталоге
    #import "data\msado15.dll" \
     no_namespace rename("EOF", "EndOfFile")


    // в файле реализации
    struct HandleCOM
    {
    HandleCOM() { ::CoInitialize(NULL); }
    ~HandleCOM() { ::CoUninitialize();  }
    } _HandleCOM_;

    inline void TESTHR(HRESULT _hr) { if FAILED(_hr) _com_issue_error(_hr); }
    void PrintComErrorCh(_com_error &e);
    void PrintProviderErrorCh(_ConnectionPtr pConnection);

    void PrintComErrorCh(_com_error &e)
    {int iCur = 0;
    char chError[MAX_PATH];
    _bstr_t bstrSource(e.Source());
    _bstr_t bstrDescription(e.Description());

    iCur += wsprintf(chError + iCur, "Error\n");
    iCur += wsprintf(chError + iCur, "\tCode = %08lx\n", e.Error());
    iCur += wsprintf(chError + iCur, "\tCode meaning = %s\n", e.ErrorMessage());
    iCur += wsprintf(chError + iCur, "\tSource = %s\n", (LPCSTR) bstrSource);
    iCur += wsprintf(chError + iCur, "\tDescription = %s\n", (LPCSTR) bstrDescription);

    AfxMessageBox(chError);

    }

    void PrintProviderErrorCh(_ConnectionPtr pConnection)
    {int iCur = 0;
    char chError[MAX_PATH];
    // Print Provider Errors from Connection object.
    // pErr is a record object in the Connection's Error collection.
    ErrorPtr pErr = NULL;
    if( (pConnection->Errors->Count) > 0)
    {
    long nCount = pConnection->Errors->Count;
    // Collection ranges from 0 to nCount -1.
    for(long i = 0; i < nCount; i++)
    {
    pErr = pConnection->Errors->GetItem(i);
    wsprintf(chError, "Error number: %x\t%s\n", pErr->Number,
     (LPCSTR) pErr->Description);
    AfxMessageBox(chError);
    }
    }
    };


    //Connection string
    //для аксеса
    m_Conn=_T("Driver={Microsoft Access Driver (*.mdb)};DBQ=C:/<path>/store.mdb");
    //для DBF
    m_Conn=_T("Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277; Dbq=E:\\<path>\\GrodnoOnLine_1");
    //для SQL Server
    m_Conn=_T("Provider=SQLOLEDB.1;Data Source=(local);"
       "Initial Catalog=myDatabaseName;"
       "User ID=myUsername;Password=myPassword;");

    //функция запроса
    AnyFonction
    {_RecordsetPtr pRs = NULL;
    int i = 0;
    float fTatal = 0, fPr = 0;
    m_Qry = _T("SELECT* FROM ITEMS");

    try
    {
    TESTHR(pRs.CreateInstance(__uuidof(Recordset)));
    pRs->CursorType = adOpenStatic;
    pRs->CursorLocation = adUseClient;
    pRs->Open(m_Qry, m_Conn, adOpenStatic, adLockBatchOptimistic, adCmdText);

    while(!(pRs->EndOfFile))
    {
     m_lIDDept  = pRs->GetFields()->GetItem("IDDept")->GetValue();
     m_lIDItem  = pRs->GetFields()->GetItem("IDItem")->GetValue();
     m_strBarCode = (char*) ((_bstr_t) pRs->GetFields()->GetItem("BarCode")->GetValue());
     m_strEcrCode = (char*) ((_bstr_t) pRs->GetFields()->GetItem("EcrCode")->GetValue());
     m_strInternalCode  = (char*) ((_bstr_t) pRs->GetFields()->GetItem("InternalCode")->GetValue());
     m_strDescription   = (char*) ((_bstr_t) pRs->GetFields()->GetItem("Description")->GetValue());
     m_strDescriptionCR = (char*) ((_bstr_t) pRs->GetFields()->GetItem("DescriptionCR")->GetValue());
     m_iCondition = pRs->GetFields()->GetItem("Condition")->GetValue();
     m_fPrice1  = pRs->GetFields()->GetItem("Price1")->GetValue();
    //  m_fQuantity     = pRs->GetFields()->GetItem("Quantity")->GetValue();

     m_ctrlItemEdit.AddSearchString(m_strBarCode);
     pRs->MoveNext();
    }

    pRs->Close();

    }
    catch(_com_error &e)
    {_variant_t vtConnect;

    vtConnect = pRs->GetActiveConnection();

    switch(vtConnect.vt)
    {
     case VT_BSTR:
        PrintComErrorCh(e);
     break;
     case VT_DISPATCH:
        PrintProviderErrorCh(vtConnect);
     break;
     default:
        printf("Errors occured.");
     break;
    }
    }
    }
    юзайте тег
    Код (Text):
     
     
  5. Guest

    Guest Гость

    Большое спасибо за пример. Обязательно попробую использовать, а я в Builder обычно использую TADOConnection, TADODataSet и другие классы для работы с ADO.
     
  6. Shader88

    Shader88 Гость

    Для: SVAN

    Привет! :)

    Я тут не много запоздало..... :(

    Вообще у меня есть модуль писанный правда на Pascale, но читает все без косяков..... :)

    Если надо обращайся солью..... :)

    Успехов! :)
     
  7. Guest

    Guest Гость

    Привет, если не можешь, вышли пожалуйста пожалуйста исходники на SVAN@pochtamt.ru. Интересно очень посмотреть, заранее благодарен.
     
  8. Guest

    Guest Гость

    <!--QuoteBegin-Guest+9:02:2006, 15:21 -->
    <span class="vbquote">(Guest @ 9:02:2006, 15:21 )</span><!--QuoteEBegin-->Привет, если не можешь, вышли пожалуйста пожалуйста исходники на SVAN@pochtamt.ru. Интересно очень посмотреть, заранее благодарен.
    [snapback]30391" rel="nofollow" target="_blank[/snapback]​
    [/quote]

    То есть, если можешь :)
     
  9. bpiter

    bpiter Member

    Регистрация:
    23 май 2006
    Сообщения:
    5
    Симпатии:
    0
    Хочю успокоить :rolleyes:. Это класно расписано. Но в Билдере всё проще.
    Никаких путе прописывать ненужно.

    В ADOConnection компоненте указываешь Build->Melkosoft Jet 4.0 OLE DB Provider.
    Это дает твоему приложению мультисовместимость со всеми версиями Винды. Даже 95.
    Я сам проверял - подключил MDB-файл базы Access 2003 без установленого Офиса или Аксеса.
    Глюков нет вообще. Правда ключи (после ввода) обновлять нужно почаще, а то начинает таблица сыпаться - то данных не запоминает, то непонятные ошибки выдает. А если это основное правило соблюдать, то не будет ни глюков, ни головной боли. Кстати я очень уважаю Мелкософт за такой подарок всем программистам. В базе/файле можно создавать немеряное количество таблиц. Я делал около 50 шт. и всё работало без тормозов. Каждая таблица может содержать более 10 млн. записей (этого я не проверял, но люди говорят, что это вранье). Также необходимо иногда делать компрессию таблиц в Аксесе. Это ускоряет работу. Кстати, я видел несколько функций как делать сжатие, но из моих программ этого добиться не смог. Так, что если кто знает как это делать, киньте мне на мыло исходничек. Буду очень благодарен. :)

    Ну, дальше я покажу код подключения базы (отлаженный листинг формы с календарем "Unit2.cpp" - вводиш дату создается база за год методом копирования из резервного файла):

    Код (Text):
    //---------------------------------------------------------------------------

    #include <vcl.h>
    #pragma hdrstop

    #include "Unit2.h"
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm2 *Form2;
    //---------------------------------------------------------------------------
    __fastcall TForm2::TForm2(TComponent* Owner)
    : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm2::Button1Click(TObject *Sender)
    {
    Form1->Panel3->Caption=FormatDateTime("dd.mm.yyyy",CDate->Date);

    AnsiString sFDB=ExtractFileDir(ParamStr(0))+"\\"+FormatDateTime("yyyy",CDate->Date)+".mdb";
    AnsiString sFDef=ExtractFileDir(ParamStr(0))+".\\p_default.mdb";

    if(!FileExists(sFDB))
    {
    if(!FileExists(sFDef))Application->Terminate();
    else
    {
    if(!CopyFile(sFDef.c_str(), sFDB.c_str(), true))
    {
    ShowMessage("Не можу створити нову базу даних!");
    Application->Terminate();
    }
    else
    {
    Form1->TNew->Active=false;
    Form1->TLists->Active=false;
    Form1->TFilters->Active=false;
    Form1->QBaza->Active=false;
    Form1->TMKX->Active=false;
    Form1->TConf->Active=false;

    Form1->ADOConnection1->Connected=false;

    Form1->ADOConnection1->ConnectionString=  "Provider=Microsoft.Jet.OLEDB.4.0;"
    "Password=;User ID=Admin;Data Source="+sFDB+";"
    "Mode=ReadWrite;Extended Properties=;"
    "Jet OLEDB:System database=;Jet OLEDB:Registry Path=;"
    "Jet OLEDB:Database Password=;Jet OLEDB:Engine Type=4;"
    "Jet OLEDB:Database Locking Mode=0;"
    "Jet OLEDB:Global Partial Bulk Ops=2;"
    "Jet OLEDB:Global Bulk Transactions=1;"
    "Jet OLEDB:New Database Password=;"
    "Jet OLEDB:Create System Database=False;"
    "Jet OLEDB:Encrypt Database=False;"
    "Jet OLEDB:Don't Copy Locale on Compact=False;"
    "Jet OLEDB:Compact Without Replica Repair=False;"
    "Jet OLEDB:SFP=False";

    Form1->ADOConnection1->Connected=true;

    Form1->TNew->Active=true;
    Form1->TLists->Active=true;
    Form1->QBaza->Active=true;
    Form1->TFilters->Active=true;
    Form1->TMKX->Active=true;
    Form1->TConf->Active=true;

    Form1->Panel5->Caption=IntToStr(Form1->QBaza->RecordCount);
    }
    }
    }
    else
    {
    Form1->TNew->Active=false;
    Form1->TLists->Active=false;
    Form1->TFilters->Active=false;
    Form1->QBaza->Active=false;
    Form1->TMKX->Active=false;
    Form1->TConf->Active=false;

    Form1->ADOConnection1->Connected=false;

    Form1->ADOConnection1->ConnectionString=  "Provider=Microsoft.Jet.OLEDB.4.0;"
    "Password=;User ID=Admin;Data Source="+sFDB+";"
    "Mode=ReadWrite;Extended Properties=;"
    "Jet OLEDB:System database=;Jet OLEDB:Registry Path=;"
    "Jet OLEDB:Database Password=;Jet OLEDB:Engine Type=4;"
    "Jet OLEDB:Database Locking Mode=0;"
    "Jet OLEDB:Global Partial Bulk Ops=2;"
    "Jet OLEDB:Global Bulk Transactions=1;"
    "Jet OLEDB:New Database Password=;"
    "Jet OLEDB:Create System Database=False;"
    "Jet OLEDB:Encrypt Database=False;"
    "Jet OLEDB:Don't Copy Locale on Compact=False;"
    "Jet OLEDB:Compact Without Replica Repair=False;"
    "Jet OLEDB:SFP=False";

    Form1->ADOConnection1->Connected=true;

    Form1->TNew->Active=true;
    Form1->TLists->Active=true;
    Form1->QBaza->Active=true;
    Form1->TFilters->Active=true;
    Form1->TMKX->Active=true;
    Form1->TConf->Active=true;

    Form1->Panel5->Caption=IntToStr(Form1->QBaza->RecordCount);
    }

    if (Form1->TConf->Active==true)
    {
    Form1->TConf->First();

    while(!Form1->TConf->Eof)
    {
    if(Form1->TConf->FieldByName("Command")->AsString=="RAYON")
    {
    if(Form1->TConf->FieldByName("Name")->AsString!="")
    {
    Form1->Panel8->Caption=Form1->TConf->FieldByName("Name")->AsString;
    Form1->Panel6->Caption=Form1->TConf->FieldByName("Size")->AsString;
    //Form1->Panel5->Caption=IntToStr(Form1->QBaza->RecordCount);
    }
    else
    {
    Form1->Panel8->Caption="Не вибрано район!";

    }
    }

    Form1->TConf->Next();
    }
    Form1->Panel5->Caption=IntToStr(Form1->QBaza->RecordCount);
    Form1->TConf->First();
    }

    if (Form1->TNew->Active==true)
    {
    Form1->TNew->First();
    int i=0;
    while(!Form1->TNew->Eof)
    {
    if(Form1->TNew->FieldByName("Table")->AsString!="")
    {
    Form1->QBaza->Fields->Fields[i]->DisplayLabel=Form1->TNew->FieldByName("Name")->AsString;
    Form1->QBaza->Fields->Fields[i]->Visible=Form1->TNew->FieldByName("Visible")->AsBoolean;
    Form1->QBaza->Fields->Fields[i]->DisplayWidth=Form1->TNew->FieldByName("Table_SIZE")->AsInteger;
    }
    //else Form1->QBaza->Fields->Fields[i]->Visible=false;
    Form1->TNew->Next();
    i++;
    }
    Form1->TNew->First();
    }

    Close();
    }
    //---------------------------------------------------------------------------
     
  10. malor

    malor Active Member

    Регистрация:
    30 апр 2007
    Сообщения:
    27
    Симпатии:
    0
    Я создаю строку ConnectionString у компонента ADOConnection. На вкладке поставщик данных выбрал Microsoft Jet 4.0 OLE DB Provider. Жму 'Далее', 'Выберите или введите имя базы данных:' - жму кнопку с троеточием, иду по дереву каталогов до того места, где у меня лежит табличка Paradox(создавал в Database Desktop). Но добравшись до нужной папки файла там нет, т.к. внизу в Типе файлов(подлежащих отображению) написано 'Базы данных Microsoft Access (*.mdb)'. Если сменить на 'Все файлы', то конечно я увижу файлы моей таблицы. Если выберу свой файл namefile.db, затем стеру слово Admin в графе 'Пользователь' и нажму 'Проверить подключение', то выдаст:"Не выполнена проверка подключения при инициализации поставщика. Нераспознаваемый формат базы данных:'C:\pathtofile\namefile.db'"
    Что делать?

    Delphi 7, WinXP
     
  11. bpiter

    bpiter Member

    Регистрация:
    23 май 2006
    Сообщения:
    5
    Симпатии:
    0
    Хм... Мой метод пригоден только для Аксесовских таблиц... Даный тип таблиц я рекомендую использовать исключитьельно из своего жизненного опыта. Так-как Парадоксовские таблицы очень капризные и часто сыпятся с полной потерей данных. Тем более, что нет методов и компонентов, которые делали бы Парадоксовскую баз автономной на компьютерах, где отсутствуют необходимые драйвера. Короче, на каждый комп, куда ставишь базу, нужно тянуть 50 Мб дров, которые "геморно" нужно устанавливать прописывая каждую длл-ку... мдя... если есть желание, то работайте и дальше с Парадоксом. Для подключения таблицы нужно всего два компонента "Table" и "DataSource". Если таблица и программа в одной папке то путь к базе можно сделать относительным... хотя... это срабатывает в Парадоксе не очень часто...
     
  12. bpiter

    bpiter Member

    Регистрация:
    23 май 2006
    Сообщения:
    5
    Симпатии:
    0
    Хм... Мой метод пригоден только для Аксесовских таблиц... Даный тип таблиц я рекомендую использовать исключитьельно из своего жизненного опыта. Так-как Парадоксовские таблицы очень капризные и часто сыпятся с полной потерей данных. Тем более, что нет методов и компонентов, которые делали бы Парадоксовскую баз автономной на компьютерах, где отсутствуют необходимые драйвера. Короче, на каждый комп, куда ставишь базу, нужно тянуть 50 Мб дров, которые "геморно" нужно устанавливать прописывая каждую длл-ку... мдя... если есть желание, то работайте и дальше с Парадоксом. Для подключения таблицы нужно всего два компонента "Table" и "DataSource". Если таблица и программа в одной папке то путь к базе можно сделать относительным... хотя... это срабатывает в Парадоксе не очень часто...
     
Загрузка...
Похожие Темы - Проблема кодировкой БД
  1. JohnLemon
    Ответов:
    16
    Просмотров:
    1.241
  2. Borodo
    Ответов:
    1
    Просмотров:
    1.288
  3. AgniXRudra
    Ответов:
    2
    Просмотров:
    54
  4. Zloikaktus
    Ответов:
    0
    Просмотров:
    31
  5. c0de3r
    Ответов:
    5
    Просмотров:
    153
Статус темы:
Закрыта.

Поделиться этой страницей