Với một chút trợ giúp từ Mat, tôi đã có thể tìm ra vấn đề là gì, nhưng vì anh ấy không đưa ra dưới dạng câu trả lời, tôi sẽ phải trả lời nó để có thể chia sẻ cho những người có cùng một vấn đề và cũng để đánh dấu là đã trả lời.
Vì vậy, vấn đề của tôi là tôi không thể kết nối với cơ sở dữ liệu. Như Mat đã đề xuất, tôi nên sử dụng thông tin lỗi mở rộng, được gọi là SQLGetDiagRec
và cũng sửa chữa các đối số theo tài liệu. Cho tôi một chút thời gian để tìm hiểu cách sử dụng SQLGetDiagRec
hàm hoạt động, nhưng sau khi tôi quản lý để chuyển đổi wchar_t
thành char *
Tôi có thể thấy lỗi mà nó đang tạo ra.
Nỗ lực kết nối đã cho tôi lỗi Data source not found and no default driver specified
. Điều đó cho tôi một manh mối, cho thấy tôi đã viết chuỗi kết nối không chính xác hoặc chuỗi văn bản đã bị hiểu sai hoặc hiểu sai bằng cách nào đó.
Thực hiện một số tìm kiếm trên mạng đã cho tôi hiểu rõ rằng chuỗi này đã bị hiểu sai và để khắc phục, tôi phải biến nó thành một chuỗi theo nghĩa đen. Chắc chắn là đủ, đặt một L trước chuỗi đã giải quyết được vấn đề đó!
retcode = SQLDriverConnect(hdbc, 0,
(SQLWCHAR*)L"DSN=TestConnection;SERVER=localhost;UID=user;PWD=password;DRIVER=MySQL Server;",
_countof(L"DSN=TestConnection;SERVER=localhost;UID=user;PWD=password;DRIVER=MySQL Server;"),
OutConnStr, 255, &OutConnStrLen, SQL_DRIVER_COMPLETE);
Đồng thời, tôi đã học được cách loại bỏ lời nhắc, điều này khá dễ dàng để tìm ra sau khi khắc phục sự cố ban đầu. Chỉ định null cho tay cầm cửa sổ, đặt hoàn thành trình điều khiển thành SQL_DRIVER_COMPLETE
và đảm bảo rằng bạn thêm tất cả thông tin cần thiết vào chuỗi kết nối.
Vì vậy, vấn đề tiếp theo tôi gặp phải với truy vấn với SQLExecDirect
đã đưa ra lỗi nói rằng Syntax error or access violation
. Vấn đề rõ ràng là giống như với chuỗi kết nối. Chắc chắn là đủ
retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);
Làm việc như một sự quyến rũ.
Đây là toàn bộ mã, đầy đủ chức năng:
#include <iostream>
#include <windows.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
#include <string>
using namespace std;
int main(){
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLRETURN retcode;
SQLWCHAR OutConnStr[255];
SQLSMALLINT OutConnStrLen;
// Allocate environment handle
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
// Set the ODBC version environment attribute
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
// Allocate connection handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
// Set login timeout to 5 seconds
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
// Connect to data source
retcode = SQLDriverConnect(
hdbc,
0,
(SQLWCHAR*)L"DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL Server;",
_countof(L"DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL Server;"),
OutConnStr,
255,
&OutConnStrLen,
SQL_DRIVER_COMPLETE );
// Allocate statement handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
// Process data
retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);
if (retcode == SQL_SUCCESS) {
SQLINTEGER sTestInt, cbTestStr, cbTestInt, cbTestFloat, iCount = 1;
SQLFLOAT dTestFloat;
SQLCHAR szTestStr[200];
while (TRUE) {
retcode = SQLFetch(hstmt);
if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {
cout<<"An error occurred";
}
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){
SQLGetData(hstmt, 1, SQL_C_CHAR, szTestStr, 200, &cbTestStr);
SQLGetData(hstmt, 2, SQL_C_ULONG, &sTestInt, 0, &cbTestInt);
SQLGetData(hstmt, 3, SQL_C_DOUBLE, &dTestFloat, 0,&cbTestFloat);
/* Print the row of data */
cout<<"Row "<<iCount<<":"<<endl;
cout<<szTestStr<<endl;
cout<<sTestInt<<endl;
cout<<dTestFloat<<endl;
iCount++;
} else {
break;
}
}
}else{
cout<<"Query execution error."<<endl;
}
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
SQLDisconnect(hdbc);
}else{
cout<<"Connection error"<<endl;
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
system("pause");
return 0;
}
Hãy cứ thể hiện, ngay cả điều nhỏ nhặt nhất cũng có thể khiến mọi thứ thất bại.
Cảm ơn Mat đã giúp đỡ.