使用ODBC连接到SQL SERVER 2008

6

我正在使用一台W32计算机,试图与数据库建立连接。为此,我尝试启动一个示例程序进行测试:

#include <iostream>
#include <windows.h>
#include <sqltypes.h>
#include <sql.h>
#include <sqlext.h>

using namespace std;

void show_error(unsigned int handletype, const SQLHANDLE& handle){
    SQLCHAR sqlstate[1024];
    SQLCHAR message[1024];
    if(SQL_SUCCESS == SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, message, 1024, NULL))
        cout<<"Message: "<<message<<"\nSQLSTATE: "<<sqlstate<<endl;
}

int main(){

    SQLHANDLE sqlenvhandle;
    SQLHANDLE sqlconnectionhandle;
    SQLHANDLE sqlstatementhandle;
    SQLRETURN retcode;

    if(SQL_SUCCESS!=SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlenvhandle))
        goto FINISHED;

    if(SQL_SUCCESS!=SQLSetEnvAttr(sqlenvhandle,SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0))
        goto FINISHED;

    if(SQL_SUCCESS!=SQLAllocHandle(SQL_HANDLE_DBC, sqlenvhandle, &sqlconnectionhandle))
        goto FINISHED;

    SQLCHAR retconstring[1024];
    switch(SQLDriverConnect (sqlconnectionhandle,
                NULL,
                (SQLCHAR*)"DRIVER={SQL Server};SERVER=localhost, 1433;DATABASE=MyDatabase;UID=sa;PWD=Admin-123;",
                SQL_NTS,
                retconstring,
                1024,
                NULL,
                SQL_DRIVER_NOPROMPT)){
        case SQL_SUCCESS_WITH_INFO:
            show_error(SQL_HANDLE_DBC, sqlconnectionhandle);
            break;
        case SQL_INVALID_HANDLE:
        case SQL_ERROR:
            show_error(SQL_HANDLE_DBC, sqlconnectionhandle);
            goto FINISHED;
        default:
            break;
    }

    if(SQL_SUCCESS!=SQLAllocHandle(SQL_HANDLE_STMT, sqlconnectionhandle, &sqlstatementhandle))
        goto FINISHED;

    if(SQL_SUCCESS!=SQLExecDirect(sqlstatementhandle, (SQLCHAR*)"select * from testtable", SQL_NTS)){
        show_error(SQL_HANDLE_STMT, sqlstatementhandle);
        goto FINISHED;
    }
    else{
        char name[64];
        char address[64];
        int id;
        while(SQLFetch(sqlstatementhandle)==SQL_SUCCESS){
            SQLGetData(sqlstatementhandle, 1, SQL_C_ULONG, &id, 0, NULL);
            SQLGetData(sqlstatementhandle, 2, SQL_C_CHAR, name, 64, NULL);
            SQLGetData(sqlstatementhandle, 3, SQL_C_CHAR, address, 64, NULL);
            cout<<id<<" "<<name<<" "<<address<<endl;
        }
    }

FINISHED:
    SQLFreeHandle(SQL_HANDLE_STMT, sqlstatementhandle );
    SQLDisconnect(sqlconnectionhandle);
    SQLFreeHandle(SQL_HANDLE_DBC, sqlconnectionhandle);
    SQLFreeHandle(SQL_HANDLE_ENV, sqlenvhandle);

}

问题在于我尝试编译时遇到了许多问题,比如未声明的类型。
'SQLHANDLE' has not been declared
'SQLHDESC' was not declared in this scope

我已经链接了libodbccpp32.alibodbc32.a库。那么我做错了什么呢?


错误似乎表明您没有包含描述sqlhandle/sqlhdesc的odbc头文件。我认为它在ntodbc.h中。 - Dan
你知道我可以在哪里获取那个头文件吗? - Filgera
看起来那个错误是我使用的Sybase SDK特定的。这里是微软的一些列表:http://msdn.microsoft.com/en-us/library/ms713603%28v=VS.85%29.aspx。实际上,sqltypes.h是微软SDK的一个头文件。我已经将它安装在C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include。你的编译错误中还有更多细节吗?你的包含路径是什么样子的? - Dan
实际上,几乎所有的错误都源自这些错误,并且在某种程度上是相同的(“error: 'SQLHDESC' was not declared in this scope”)。包含路径是指向mingw头文件的路径,其中包括了所有这些文件。我在日志中没有看到包含文件错误。 - Filgera
事实上,我发现添加头文件 stdafx 可以解决这个问题。但问题是我包含路径的顺序(这很奇怪,因为在示例中它们是这样的)。为了避免问题,我将包含路径的正确顺序也包括在内。 - Filgera
3个回答

1

头文件的顺序并不重要。只需确保您的项目在其属性中包含以下包含目录:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include

在编程中找到的(先验地):
windows.h
sqlext.h
sqltypes.h
sql.h

这足以使你的命令被识别并编译,而不会出现任何问题。

1

我发现在使用stdafx.h头文件时,包含的顺序应该改为:

#include <iostream>
#include <windows.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <sql.h>

-1

只需像这样更改包含声明:

#include <iostream>
#include <windows.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接