Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Oracle > Проблема использования OO4O


Автор: Fazil6 5.6.2006, 13:30
у меня проблема вызвать ХП с передачей аргументов через параметры. Есть ли какие-то подводные камни, которые не бросаются в глаза в документации и которые я проглядел.
При попытке вызова 
Код

odb.ExecuteSQL(statement);

возвращает OFAILURE и вызов odb.GetErrorText() выдает "ORA-01008 не все переменные привязаны"
Количество параметров соответствует количеству аргументов.
Пробовал задавать все аргументы через параметры, пробовал задавать только входные, картина не меняется. 
Если просто разбираю имеющиеся данные и формирую вызов ХП через запрос подставляя туда значения - все пучком. 
После добавления параметров GetErrorText() для OParameterCollection не выдает никаких ошибок.

Короче, есть у кого-нибудь какие-нить соображения или впадать в отчаяние? 

Автор: Sqlninja 5.6.2006, 14:05
нужен код ХП. 

Автор: Fazil6 5.6.2006, 14:13
Цитата

нужен код ХП.

с этим небольшая проблема. Что именно интересует?
вот объявление могу привести
Код

PROCEDURE delivery_message1 (
    id_in              IN  interface_table.id%TYPE,
    receiver_id_in     IN  interface_table.sender_id%TYPE,
    sender_id_in       IN  interface_table.sender_id%TYPE, 
    command_id_in      IN  interface_table.command_id%TYPE, 
    command_param_in   IN  interface_table.command_param%TYPE, 
    priority_in        IN  interface_table.priority%TYPE, 
    business_info_v_in IN  interface_table.business_info_v%TYPE, 
    business_info_b_in IN  interface_table.business_info_b%TYPE, 
    error_code_out     OUT NUMBER -
  );

4, 5, 7 и 8 VarChar2
остальные NUMBER 

Автор: Sqlninja 5.6.2006, 14:31
ну а код вызова можете привести полностью? 

Автор: Fazil6 5.6.2006, 14:55
можем
Код

// как грится текущий вариант моих мучений
         std::string query = "Begin " + proc_name + " (  "; // proc_name - здесь ошибки нет
    OParameterCollection pc = odb.GetParameters();

         Params_t::iterator i = p.begin();  // Params_t - std::list  это список объектов параметров
    while(true)
    {
        ProcParam_t proc_p = *i;   // указатель на параметр (это мой класс)
        if(proc_p->type == OTYPE_NUMBER)
        {    
            pc.Add(proc_p->name.c_str(), int(proc_p->data.numb), proc_p->in_out, proc_p->type); // proc_p->name.c_str() -        
                                                                                                                                                 //проверено, вставляет правильно
        }else
            if(proc_p->type == OTYPE_VARCHAR2)
            {
                if(proc_p->name == "pbusiness_info_b_in")
                pc.Add(proc_p->name.c_str(), NULL,2000, OPARAMETER_INVAR, OTYPE_BLOB);
                else pc.Add(proc_p->name.c_str(), proc_p->data.str->c_str(),2000, proc_p->in_out, proc_p->type);
            //MessageBox(0,proc_p->data.str->c_str(),0,0);  - это пробовал проверять строки - тоже все правильно
            }else
                throw std::runtime_error("Oracle::RunProcedure нереализованный тип параметра. Ошибка.");
        
        query = query + ":" + proc_p->name;
        ++i;
        if(i == p.end()) break;

        query = query + ", ";

    }
    
    query = query + ");  end;";

    //query в этом месте выглядит без каких-то заметных ошибок, т.е. то, что я хотел получить
         // "Begin name1.name2(:pid_in, :preceiver_id_in, .....  , :error_code_out); end;"
    ORACLERESULT r = Run(query); // внутри этой функции старкует транзакция, вызывается ExecuteSQL и в зависимости от 
                                                            // результата Commit или Rollback
                                                            // но по этому пути до Commit не доходит
    

 

Автор: Sqlninja 5.6.2006, 14:59
мне нужен код где вызывается метод ExecuteSql(), тот что в вашем первом сообщении, плз. 

Автор: Fazil6 5.6.2006, 15:04
вот только сейчас вот чего нарыл.
Перед вызовом решил проверить параметры.
С числами нет проблем, но вот со строками какой-то папандос (или я с проверкой накосячил?)
Код

         char b[2000];    
    char b1[2000];
    char b2[2000];
    char b3[2000];
    int len = 2000;
        odb.GetParameters().GetParameter("pcommand_id_in").GetValue((const char**)&b);
        odb.GetParameters().GetParameter("pcommand_param_in").GetValue((const char**)&b1, &len);
        odb.GetParameters().GetParameter("pbusiness_info_v_in").GetValue((const char**)&b2, &len);

        odb.GetParameters().GetParameter("pbusiness_info_b_in").GetValue((const char**)&b3, &len);


последний параметр сохранялся как NULL и с ним нет проблем первый байт 0 как положено, а остальные имеют в первых 3-х байтах кракозябры (причем первый отрицательный) потом 0 и дальше видно, что не записывалось ничего, и причем все 3 параметра (имею в виду значения записанные в b, b1 и b2) имеют одинаковое перекошенное значение. Когда передавал в Аdd проверял, там все было нормально

Добавлено @ 15:09 
Цитата

мне нужен код где вызывается метод ExecuteSql(), тот что в вашем первом сообщении, плз. 

хм.... ну вот.
Код

ORACLERESULT Oracle::Run(const std::string& statment)
{
    if(!odb.IsOpen()) return DISCONNECTED_ORC;
    
    odb.BeginTrans();
    if( odb.ExecuteSQL(statment.c_str()) == OFAILURE)
    {
        ::MessageBox(0,odb.GetErrorText(), 0,0);
        odb.Rollback();
        return ERROR_ORC;
    }
    odb.CommitTrans();
    
    return SUCCESS_ORC;
}

 

Автор: Sqlninja 5.6.2006, 15:11
ну вы мне дадите ExecuteSql() или нет?  smile  

Автор: Fazil6 5.6.2006, 15:20
Цитата

ну вы мне дадите ExecuteSql() или нет?

ни хрена не понимаю....
ну 3-я строка в функции Run!!! Мы разве не об этом говорим? 

Автор: Sqlninja 5.6.2006, 15:31
мдя. SQL отсюда плохо виден...  statment как-то реально получить?

Добавлено @ 15:34 
Цитата(Fazil6 @  5.6.2006,  15:20 Найти цитируемый пост)
ну 3-я строка в функции Run!!! Мы разве не об этом говорим? 

relax, relax, man - мы одновременно запостились. 

Автор: Fazil6 5.6.2006, 15:42
ну для примера он выглядит вот так. Я здесь ошибок не вижу
Код

"Begin name1.name2(:pid_in, :preceiver_id_in, :psender_id_in, :pcommand_id_in, :pcommand_param_in, :ppriority_in, :pbusiness_info_v_in, :pbusiness_info_b_in , :error_code_out); end;"

пробовал и так формировать
Код

"Declare error_code_out NUMBER; Begin name1.name2(:pid_in, :preceiver_id_in, :psender_id_in, :pcommand_id_in, :pcommand_param_in, :ppriority_in, :pbusiness_info_v_in, :pbusiness_info_b_in , error_code_out); end;"

результат один и тот же
 

Автор: Sqlninja 5.6.2006, 15:57
да нету здесь ошибок - ошибка в процедуре name1.name2() которую я так до сих пор и не увидел... 

Автор: Fazil6 5.6.2006, 16:09
Цитата

да нету здесь ошибок - ошибка в процедуре name1.name2() которую я так до сих пор и не увидел... 

Какие ошибки по твоему там могут быть?
там ошибок на эту тему не должно быть. БД давно в комерческой эксплуатации и это одна из самых часто используемых функций.
Если я не использую параметры, а пишу значения прямо в запросе вызова этой ХП, то тоже все работает нормально.  

Автор: Sqlninja 5.6.2006, 16:12
а какая версия OCI? 

Автор: Fazil6 5.6.2006, 16:29
я пока с Oracl`om только 2-й день дело имею и панятия не имею, что ты понимаешь под версией OCI.
Ладно, без параметров работает и хрен с ним. Попозже попробую по одному параметру добавлять и всетаки разобраться где тут собака порылась.

Добавлено @ 16:30 
спасибо за желание помочь 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)