c++ - Poco 1.5.2 C++ ODBC 在插入时抛出异常

标签 c++ sql-server-2008 odbc poco-libraries

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

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

一切正常,直到它提交大插入命令的那一刻。它抛出异常,我不明白为什么。

在这里,我将给出正在执行的代码的简单概述。假设变量存在并被初始化。 我运行的 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. 我如何知道 Session 处于什么状态?
  2. 有没有办法询问 Poco 出了什么问题并让它打印一条错误消息?
  3. 是否需要设置任何特殊的东西才能像我一样在文本中一起指定一个大的插入语句?我试过使用 ?占位符,或执行单个语句,但在这方面总是给我一个异常(exception)。
  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;
    }

非常感谢您的帮助或关于如何改进此问题的任何建议。

最佳答案

1.: Session 类中有各种查询成员 - isConnected()、canTransact()、isTransaction() ...(如果这是您要查找的;如果不是,请参阅下一个答案)


<强>1。和 2.: 将您的语句包装到 try/catch block 中:

#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 驱动程序的东西都可以。

关于c++ - Poco 1.5.2 C++ ODBC 在插入时抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27303972/

相关文章:

c++ - 常量,但仅适用于此范围的其余部分

c++ - C++ 中的 case/switch 语句

sql-server-2008 - 在 SQL Server 2008 中格式化 SYSDATETIMEOFFSET

c# - 通过 SQL 将属性存储在 Arraylist 中并显示在文本框中

MySQL ODBC 更新查询非常慢

php - mysql_pconnect 与 odbc_connect (PHP)

c++ - 实体组件系统 - 组件相互需要

c++ - 如何在 OpenNIGrabber 上设置特定的设备 ID?

sql - 比较 SQL 中以逗号分隔的字符串

sql-server-2008 - SQL Server 索引的优化