2014-12-04 3 views
0

텍스트 파일에서 3D 메쉬에 대한 정보를 읽고, 메쉬로 데이터를 저장하고, 메쉬에서 일부 후 처리를 수행 한 다음 볼륨과 같은 정보를 수집하는 프로그램이 있습니다. , 질량 중심 등Poco 1.5.2 C++ ODBC가 삽입시 예외를 throw합니다.

프로그램에는 두 개의 스레드가 있습니다. 주 스레드는 두 번째 스레드를 시작하고 파일을 읽고 처리 한 다음 두 번째 스레드를 기다립니다. 처리의 일부로, 방금 읽은 메쉬에 대한 정보를 대기열에 넣습니다. 두 번째 스레드는 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. 세션이 어떤 상태에 있는지 어떻게 알 수 있습니까?
  2. Poco에게 무엇이 잘못되었는지 물어보고 오류 메시지를 인쇄 할 수있는 방법이 있습니까?
  3. 큰 삽입 문을 모두 같이 텍스트로 지정할 수 있도록 설정해야하는 특별한 것이 있습니까? 나는 그것을 사용하려고 했는가? 자리 표시 자 또는 개별 문장을 실행하지만 항상 해당 부분에 대한 예외를 제공합니다.
  4. 동일한 연결에서 명령문을 실행하는 방법이 있습니까? 일반적으로 나는 INSERT INTO TableName1 (...) VALUES (...) SELECT SCOPE_IDENTITY()를 단일 작업으로 수행합니다. SQL Server Management Studio에서 명령을 시도했지만 제대로 작동합니다. 지금은 별도의 연결에서 실행되는 명령문과 같이 항상 NULL 0을 반환합니다.

더 많은 정보 :

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

1. : 세션 클래스의 다양한 쿼리 회원이있다 -는, isConnected(), canTransact(), isTransaction는() ... (그건 당신이 찾고있는 경우는없는 경우, 다음을 참조

#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; } 

: try/catch 블록으로 문을 감싸 :


1, 2 대답)

: 나는 너무 큰 성명서라고 생각하지 않습니다. 문자열 크기를 1K로 제한하는 구성 가능한 내부 설정이 있지만 이는 전체 SQL 문이 아닌 값 문자열에 적용됩니다.당신은 여전히 ​​문제라고 생각하는 경우 , 당신은 최대 필드 크기, 예를 늘릴 수 있습니다

4.

std::size_t fieldSize = 4096; //4K 
session.impl()->setProperty("maxFieldSize", Poco::Any(fieldSize)); 
: 마시고 :: 데이터 :: ODBC 구문 분석 또는에서 SQL 문을 분석하지 않습니다 방법; 그래서 그 견지에서, 당신의 ODBC 드라이버와 잘 작동합니다.

+0

감사합니다. 원래 예외가 제공된 값의 수와 잘못된 수의 열을 삽입하려고했기 때문에 원인을 파악할 수있었습니다. 내가 가진 다음 질문을 반영하기 위해 원본 게시물을 편집 중입니다. –

+0

질문 4에 대한 답변을 추가했습니다. – Alex

+0

글쎄, SQL 콘솔에 odbc 데이터 소스에 연결하면 명령을 순서대로 실행할 수 있으며 적절한 응답을 얻을 수 있습니다. Poco에서 실행하면 SCOPE_IDENTITY()는 0을 반환하며 아무것도 삽입하지 않고 새로운 연결에서 SELECT SCOPE_IDENTITY()를 호출하면 발생합니다. –