C++ SQLDriverConnect API

发布于 2024-08-17 05:11:41 字数 2569 浏览 1 评论 0原文

我正在使用 Visual Studio 2008 和 SQL Server 2008 来开发应用程序(SQL Server 在我的系统中)。我需要从数据库中获取一些字段。我正在使用 SQLDriverConnect API 连接到数据库。

如果我使用“SQL_DRIVER_PROMPT”,我将弹出窗口来选择数据源。我不希望出现这个窗口。据我了解,如果我们在连接字符串中提供的信息不足,就会出现此窗口。我想我已经提供了所有信息。我正在尝试使用 Windows 身份验证进行连接。我尝试了不同的选择,但仍然没有运气。请帮助我解决这个问题。

以下是我正在使用的代码:

//********************************************************************************
// SQLDriverConnect_ref.cpp
// compile with: odbc32.lib user32.lib
#include <windows.h>
#include <sqlext.h>

int main() {
   SQLHENV henv;
   SQLHDBC hdbc;
   SQLHSTMT hstmt;
   SQLRETURN retcode;

   SQLWCHAR OutConnStr[255];
   SQLSMALLINT OutConnStrLen;
   SQLCHAR      ConnStrIn[255] =
       "DRIVER={SQL Server};SERVER=(local);DSN=MyDSN;DATABASE=MyDatabase;Trusted_Connection=yes;";

   //SQLWCHAR *ConntStr =(SQLWCHAR *) "DRIVER={SQL Server};DSN=MyDSN;";
   HWND desktopHandle = GetDesktopWindow();   // desktop's window handle

   // 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, (SQLPOINTER*)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);

         retcode = SQLDriverConnect( // SQL_NULL_HDBC
           hdbc,
           desktopHandle,
       (SQLWCHAR *)ConnStrIn,
       SQL_NTS,
           OutConnStr,
           255, 
           &OutConnStrLen,
           SQL_DRIVER_NOPROMPT); 


            // Allocate statement handle
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {               
               retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 

               // Process data
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
                  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
               }

               SQLDisconnect(hdbc);
            }

            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
         }
      }
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
   }
}

//********************************************************************************

提前致谢, 戒日

I am using visual studio 2008 and sql server 2008 for developing application(SQL server is in my system). I need to fetch some fields from the database. I am using the SQLDriverConnect API to connect to the database.

If I use the "SQL_DRIVER_PROMPT" I will get pop window to select the data source. I don't want this window to appear. As per my understanding this window will appear if we provide insufficient information in the connection string. I think I have provided all the information. I am trying to connect with windows authentication. I tried different options but still no luck. Please help me in solving this problem.

Below is the code that I am using:

//********************************************************************************
// SQLDriverConnect_ref.cpp
// compile with: odbc32.lib user32.lib
#include <windows.h>
#include <sqlext.h>

int main() {
   SQLHENV henv;
   SQLHDBC hdbc;
   SQLHSTMT hstmt;
   SQLRETURN retcode;

   SQLWCHAR OutConnStr[255];
   SQLSMALLINT OutConnStrLen;
   SQLCHAR      ConnStrIn[255] =
       "DRIVER={SQL Server};SERVER=(local);DSN=MyDSN;DATABASE=MyDatabase;Trusted_Connection=yes;";

   //SQLWCHAR *ConntStr =(SQLWCHAR *) "DRIVER={SQL Server};DSN=MyDSN;";
   HWND desktopHandle = GetDesktopWindow();   // desktop's window handle

   // 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, (SQLPOINTER*)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);

         retcode = SQLDriverConnect( // SQL_NULL_HDBC
           hdbc,
           desktopHandle,
       (SQLWCHAR *)ConnStrIn,
       SQL_NTS,
           OutConnStr,
           255, 
           &OutConnStrLen,
           SQL_DRIVER_NOPROMPT); 


            // Allocate statement handle
            if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {               
               retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); 

               // Process data
               if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
                  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
               }

               SQLDisconnect(hdbc);
            }

            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
         }
      }
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
   }
}

//********************************************************************************

Thanks in advance,
Harsha

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

等待圉鍢 2024-08-24 05:11:41

使用SQLConnect进行连接;它没有提供提示的规定。哎呀

!坏主意。根据 SQLDriverConnect 的文档,SQLConnect 接受仅:DSN、UID 和 PW。

如果您不想允许提示,则在调用 SQLDriverConnect 时应为 hwnd 传递 NULL 指针。指定 SQL_DRIVER_NOPROMPT 作为提示选项(如您所做的那样)。如果调用失败,请检查输出响应代码并打印出消息。

以下是进行检查的方法:

boolean CHECK_STATUS(SQLRETURN rc, UCHAR *location, SQLHANDLE hnd, SQLSMALLINT hType)
{
    if (rc == SQL_SUCCESS)
    {
        printf("  ** %s: ok\n", location);
    }
    else
    {
        UCHAR *status = (rc == SQL_SUCCESS_WITH_INFO) ? "OK" : "failed" ;
        SQLRETURN _rc;
        UCHAR state[5+1];
        SQLINTEGER ecode;
        SQLSMALLINT msgLength;
        int recNumber = 0;

        printf("  ** %s: %s. rc(%d)\n", location, status, rc);

        do {
            _rc = SQLGetDiagRec(hType,
                                hnd,
                                ++recNumber, // RecNumber,
                                state,       // SQLState,
                                &ecode,      //    NativeErrorPtr,
                                NULL,        //      MessageText,
                                0,           //   BufferLength,
                                &msgLength);
            if (_rc == SQL_NO_DATA) {}
            else if (_rc != SQL_SUCCESS) {
                printf("    ** Cannot retrieve error message, reason: %d\n", _rc);
            }
            else {
                if (recNumber == 1)
                    printf("  ** SQL State: %s\n", state);
                if (rc != SQL_SUCCESS_WITH_INFO)
                    printf("  ** error code: %d\n", ecode);
                //printf("  ** %smsg length: %d\n", (rc != SQL_SUCCESS_WITH_INFO)?"error " : "", msgLength);
                if (msgLength > 0)
                {
                    UCHAR * msg = malloc((msgLength+2) * sizeof(UCHAR));
                    _rc = SQLGetDiagRec(hType,
                                        hnd,
                                        recNumber,   // RecNumber,
                                        state,       // SQLState,
                                        &ecode,      //    NativeErrorPtr,
                                        msg,         //      MessageText,
                                        msgLength+2, //   BufferLength,
                                        &msgLength);

                    printf("  ** msg %d: %s\n", recNumber, msg);
                    free(msg);
                }
            }
        } while (_rc == SQL_SUCCESS);
    }

    return (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO);
}


boolean CHECK_STATUS_DBC(SQLRETURN rc, UCHAR *location, SQLHANDLE hnd)
{
    return CHECK_STATUS(rc, location, hnd, SQL_HANDLE_DBC);
}


boolean CHECK_STATUS_ENV(SQLRETURN rc, UCHAR *location, SQLHANDLE hnd)
{
    return CHECK_STATUS(rc, location, hnd, SQL_HANDLE_ENV);
}

以下是调用调用的方法:

SQLRETURN rc;
UCHAR   *szDSN = "Driver={SQL Server};Server=hostname\\SQLEXPRESS;Database=Northwind;Trusted_Connection=Yes;";
HDBC    hdbc1 = SQL_NULL_HDBC;
HSTMT   hstmt1 = SQL_NULL_HSTMT;
boolean mustFreeConnect = FALSE;
boolean mustDisconnect = FALSE;
SQLSMALLINT dwLength;

printf("\nHello from OdbcEx1. \n");

printf("\nWill connect to %s\n", szDSN);

rc = SQLAllocEnv (&henv);
CHECK_STATUS_ENV(rc, "SQLAllocEnv", henv);

// Set the flavor of ODBC to 3.0
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
CHECK_STATUS_ENV(rc, "SQLSetEnvAttr", henv);

rc = SQLAllocConnect(henv, &hdbc1);
mustFreeConnect = CHECK_STATUS_DBC(rc, "SQLAllocConnect", henv);

rc = SQLDriverConnect(hdbc1,
                      NULL,
                      szDSN,
                      SQL_NTS,
                      NULL,
                      0,
                      &dwLength,
                      SQL_DRIVER_NOPROMPT);
mustDisconnect = CHECK_STATUS_DBC(rc, "SQLConnect", hdbc1);

Use SQLConnect to connect; it makes no provision for prompting.

Whoops!. Bad idea. According to the documentation for SQLDriverConnect, SQLConnect accepts only: DSN, UID, and PW.

You should pass the NULL pointer for the hwnd, when calling SQLDriverConnect, if you don't want to allow prompting. Specify SQL_DRIVER_NOPROMPT for the prompt option (as you do). If the call fails, examine the output response code, and print out the messages.

Here's how you can do the checks:

boolean CHECK_STATUS(SQLRETURN rc, UCHAR *location, SQLHANDLE hnd, SQLSMALLINT hType)
{
    if (rc == SQL_SUCCESS)
    {
        printf("  ** %s: ok\n", location);
    }
    else
    {
        UCHAR *status = (rc == SQL_SUCCESS_WITH_INFO) ? "OK" : "failed" ;
        SQLRETURN _rc;
        UCHAR state[5+1];
        SQLINTEGER ecode;
        SQLSMALLINT msgLength;
        int recNumber = 0;

        printf("  ** %s: %s. rc(%d)\n", location, status, rc);

        do {
            _rc = SQLGetDiagRec(hType,
                                hnd,
                                ++recNumber, // RecNumber,
                                state,       // SQLState,
                                &ecode,      //    NativeErrorPtr,
                                NULL,        //      MessageText,
                                0,           //   BufferLength,
                                &msgLength);
            if (_rc == SQL_NO_DATA) {}
            else if (_rc != SQL_SUCCESS) {
                printf("    ** Cannot retrieve error message, reason: %d\n", _rc);
            }
            else {
                if (recNumber == 1)
                    printf("  ** SQL State: %s\n", state);
                if (rc != SQL_SUCCESS_WITH_INFO)
                    printf("  ** error code: %d\n", ecode);
                //printf("  ** %smsg length: %d\n", (rc != SQL_SUCCESS_WITH_INFO)?"error " : "", msgLength);
                if (msgLength > 0)
                {
                    UCHAR * msg = malloc((msgLength+2) * sizeof(UCHAR));
                    _rc = SQLGetDiagRec(hType,
                                        hnd,
                                        recNumber,   // RecNumber,
                                        state,       // SQLState,
                                        &ecode,      //    NativeErrorPtr,
                                        msg,         //      MessageText,
                                        msgLength+2, //   BufferLength,
                                        &msgLength);

                    printf("  ** msg %d: %s\n", recNumber, msg);
                    free(msg);
                }
            }
        } while (_rc == SQL_SUCCESS);
    }

    return (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO);
}


boolean CHECK_STATUS_DBC(SQLRETURN rc, UCHAR *location, SQLHANDLE hnd)
{
    return CHECK_STATUS(rc, location, hnd, SQL_HANDLE_DBC);
}


boolean CHECK_STATUS_ENV(SQLRETURN rc, UCHAR *location, SQLHANDLE hnd)
{
    return CHECK_STATUS(rc, location, hnd, SQL_HANDLE_ENV);
}

And here's how you invoke the call:

SQLRETURN rc;
UCHAR   *szDSN = "Driver={SQL Server};Server=hostname\\SQLEXPRESS;Database=Northwind;Trusted_Connection=Yes;";
HDBC    hdbc1 = SQL_NULL_HDBC;
HSTMT   hstmt1 = SQL_NULL_HSTMT;
boolean mustFreeConnect = FALSE;
boolean mustDisconnect = FALSE;
SQLSMALLINT dwLength;

printf("\nHello from OdbcEx1. \n");

printf("\nWill connect to %s\n", szDSN);

rc = SQLAllocEnv (&henv);
CHECK_STATUS_ENV(rc, "SQLAllocEnv", henv);

// Set the flavor of ODBC to 3.0
rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
CHECK_STATUS_ENV(rc, "SQLSetEnvAttr", henv);

rc = SQLAllocConnect(henv, &hdbc1);
mustFreeConnect = CHECK_STATUS_DBC(rc, "SQLAllocConnect", henv);

rc = SQLDriverConnect(hdbc1,
                      NULL,
                      szDSN,
                      SQL_NTS,
                      NULL,
                      0,
                      &dwLength,
                      SQL_DRIVER_NOPROMPT);
mustDisconnect = CHECK_STATUS_DBC(rc, "SQLConnect", hdbc1);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文