PoC1.5.2C++ + ODBC在插入中抛出异常

PoC1.5.2C++ + ODBC在插入中抛出异常,c++,sql-server-2008,odbc,poco-libraries,C++,Sql Server 2008,Odbc,Poco Libraries,我有一个程序,它从文本文件中读取有关三维网格的信息,将数据存储为网格,对网格执行一些后处理,然后收集体积、质心等信息 该程序有两个线程: 主线程启动第二个线程,读取文件,进行处理,然后等待第二个线程。作为处理的一部分,它会将刚刚读取的网格信息放入队列中。 第二个线程使用Poco ODBC连接到SQL Server,将有关文件读取的一些初始信息放入数据库表中,然后从队列中获取信息并汇编一个可能很长的insert命令。完成此操作后,它将提交命令,执行关于所执行操作结果的最终更新命令,然后让主线程知道

我有一个程序,它从文本文件中读取有关三维网格的信息,将数据存储为网格,对网格执行一些后处理,然后收集体积、质心等信息

该程序有两个线程: 主线程启动第二个线程,读取文件,进行处理,然后等待第二个线程。作为处理的一部分,它会将刚刚读取的网格信息放入队列中。 第二个线程使用Poco ODBC连接到SQL Server,将有关文件读取的一些初始信息放入数据库表中,然后从队列中获取信息并汇编一个可能很长的insert命令。完成此操作后,它将提交命令,执行关于所执行操作结果的最终更新命令,然后让主线程知道它已完成,并终止第二个线程

一切正常,直到它提交大的insert命令为止。它抛出了一个异常,我不知道为什么

在这里,我将对正在执行的代码给出一个过于简单的概述。假设变量存在并已初始化。 我运行的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.>
我想弄清楚一些关键的事情

如何判断会话处于什么状态? 有没有办法询问Poco出了什么问题并让它打印错误消息? 我需要设置什么特殊的东西才能像我一样在文本中指定一个大的insert语句?我用过吗?占位符,或执行单个语句,但它总是给我一个例外。 有没有办法确保语句在同一连接下执行?通常我会插入TableName1…值。。。选择SCOPE_IDENTITY all作为单个操作。我已经在SQLServerManagementStudio中尝试了我的命令,它工作正常。现在,它总是返回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;
    }
非常感谢您对我如何改进此问题的帮助或建议。

1: 会话类中有各种查询成员-isConnected、canTransact、isTransaction。。。如果这就是你想要的;如果不是,请参阅下一个答案

一,。和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; }
4.:
ODBC不以任何方式解析或分析SQL语句;因此,从这个角度来看,使用ODBC驱动程序的任何东西都可以。

谢谢,我能够找出最初的异常是由于尝试插入错误的提供值数和列出的列数。我正在编辑原始帖子以反映我的下一个问题。为问题4添加了答案。好吧,当我使用sql控制台连接到odbc数据源时,我可以按顺序运行命令并得到正确的响应。当我在Poco中运行它们时,SCOPE_IDENTITY只返回0,当您从新连接调用SELECT SCOPE_IDENTITY而不插入任何内容时,就会发生这种情况。我目前正在研究事务对象,将其作为处理需要全部执行或不执行的语句集的一种方式。仍然没有找到任何例子,但希望它能在我的道路上帮助我。请参阅和
std::size_t fieldSize = 4096; //4K
session.impl()->setProperty("maxFieldSize", Poco::Any(fieldSize));