Poco 1.5.2 C ++ ODBC генерирует исключения при вставке

0

У меня есть программа, которая считывает информацию о трехмерных сетках из текстового файла, сохраняет данные в виде сетки, выполняет некоторую пост-обработку на сетке, затем собирает информацию, такую как объем, центр масс и т.д.

Программа имеет два потока: основной поток запускает второй поток, считывает файл, выполняет обработку, а затем ждет второй поток. Как часть обработки, он помещает информацию о сетках, которые он просто считывает в очередь. Второй поток подключается к SQL Server с помощью Poco ODBC, помещает некоторую начальную информацию о файле, его чтение в таблицу базы данных, затем получает информацию из очереди и собирает потенциально длинную команду вставки. Когда это будет сделано, он отправит команду, выполнит окончательную команду обновления, касающуюся результатов выполненных операций, а затем сообщит основному потоку и завершает второй поток.

Все работает, вплоть до момента подачи большой команды вставки. Он выдает исключение, и я не могу понять, почему.

Здесь я дам упрощенную схему выполняемого кода. Предположим, что существуют и инициализируются переменные. Команды poco, которые я запускаю:

using namespace Poco;
using namespace Poco::Data::Keywords;
using namespace Poco::Data;
ODBC::Connector::registerConnector();
Session session(SessionFactory::instance().create("ODBC", "Driver={SQL Server};Server=<hostname>;Database=<DB name>;Uid=<username>;Pwd=<password>;"));

session << "INSERT INTO TableName1 (SourceFileName,UserName) VALUES (?,?)",use(_filename),use(username),now;
session << "SELECT SCOPE_IDENTITY()", into(runID),now; //This always runs and returns 0.
string queryString = "Insert into TableName2 (Field1, field2, field3, field4, ...) "+
      "VALUES (val1, val2, val3, val4, ...)"+
      ",(valA, valB, valC, valD, ...),..."

session << queryString,now; 
Statement update(session);
update << "UPDATE TableName1 SET Field2 = ?, Field3 = ?, Field4 = ? WHERE Field1 = ?", use(data2), use(data3), use(data3), use(identity);
update.execute();
ODBC::Connector::unregisterConnector();
<send signal to main thread indicating being done.>

Я пытаюсь понять несколько ключевых моментов.

  1. Как я могу определить, в каком состоянии находится сеанс?
  2. Есть ли способ спросить Poco, что пошло не так, и напечатать ли сообщение об ошибке?
  3. Есть ли какие-то особые вещи, которые мне нужно настроить, чтобы иметь возможность указывать большую инструкцию insert в тексте, как я? Я пробовал использовать его? заполнители или выполнение отдельных заявлений, но это всегда дает мне исключение в этой части.
  4. Есть ли способ, чтобы инструкции выполнялись под тем же соединением? Обычно я выполнял бы INSERT INTO TableName1 (...) VALUES (...) SELECT SCOPE_IDENTITY() все как одну операцию. Я пробовал свои команды в SQL Server Management Studio и работает правильно. Прямо сейчас, он всегда возвращает 0 aka NULL, как заявления, выполняемые в отдельных соединениях.

Больше информации:

    String query = "INSERT INTO TableName1 (SourceFileName,UserName) VALUES ('"+ __file + "','" + __username + "')";
    Statement insertStmt = (session << query);
    try{insertStmt.execute(true);}
    catch(Poco::Exception exc)
    {
        cout << exc.displayText() << endl;
    }
    try{session << "SELECT SCOPE_IDENTITY() as SCOPE_IDENTITY", into(runID), now;
    cout << "Run ID: " << runID << endl;}
    catch(Poco::Exception exc)
    {
        cout << exc.displayText() << endl;
    }

Я высоко ценю вашу помощь или любые предложения о том, как я могу улучшить этот вопрос.

Теги:
sql-server-2008
odbc
poco-libraries

1 ответ

1

1. В классе Session есть различные члены запроса - isConnected(), canTransact(), isTransaction()... (если это то, что вы ищете, а если нет, см. Следующий ответ)


1. и 2.: Заверните свое выражение в блок try/catch:

#include "Poco/Data/ODBC/ODBCException.h"
//...
try 
{
 session << "INSERT INTO TableName1 (SourceFileName, UserName) VALUES (?, ?) ",use(_filename),use(username),now;
}
catch(Poco::Data::ODBC::ConnectionException& ce){ std::cout << ce.toString() << std::endl; }
catch(Poco::Data::ODBC::StatementException& se){ std::cout << se.toString() << std::endl; }

3.: Я не думаю, что проблема слишком велика. Существует настраиваемая внутренняя настройка, ограничивающая размер строки до 1K, но это относится к строкам значений, а не ко всей инструкции SQL. Если вы все еще считаете, что это проблема, вы можете увеличить размер максимального поля, например:

std::size_t fieldSize = 4096; //4K
session.impl()->setProperty("maxFieldSize", Poco::Any(fieldSize));

4.: Poco :: Data :: ODBC не анализирует и не анализирует инструкцию SQL; поэтому с этой точки зрения все, что работает с вашим драйвером ODBC, будет в порядке.

  • 0
    Спасибо, я смог выяснить, что исходное исключение было связано с попыткой вставить неверное количество введенных значений по сравнению с указанным количеством столбцов. Я редактирую оригинальное сообщение, чтобы отразить следующий вопрос, который у меня был.
  • 0
    Добавлен ответ на вопрос 4.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню