Как подключиться к SQLConnect из ODB C? - PullRequest
0 голосов
/ 20 июня 2020

Я пытаюсь подключиться к SQL серверу с ODB C и C ++, но он не может подключиться, не знаю почему. DSN уже установлен в списке User DSN.

  • Windows 10 64 бит
  • Компилятор: VC ++ 2010
  • ODB C версия: 2017.175.02.01
  • SQL Server 2019
# include "stdafx.h"
# include <windows.h>
# include <stdio.h>
# include <stdlib.h>
# include <sql.h>
# include <sqlext.h>
# include <iostream>
 
int main( )
{
    HENV henv;
    HDBC hdbc;
    RETCODE rc;
    
    SQLAllocEnv(&henv);
    SQLAllocConnect(henv, &hdbc);
 
    /* Connect to the database using the ODBC DSN definition. */
    rc = SQLConnect( hdbc,     /* Connection handle */
        (SQLWCHAR*)"db1",      /* The ODBC DSN definition */
        SQL_NTS,               /* This is a null-terminated string */
        NULL,                  /* No username required */
        0,                     /* This is a null-terminated string */
        NULL,                  /* No password required */
        0);                    /* This is a null-terminated string */

    if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
    {
        SQLFreeConnect(hdbc);
        SQLFreeEnv(henv);
        std::cout << "FAIL\n";
    }
    else{
        SQLFreeConnect(hdbc);
        SQLFreeEnv(henv);
        std::cout << "YEA! \n";
    }

    /* Exit this program. */
    system("pause");
    return( 0 );
}

Решение: необходимо объявить тип переменной и установить ее значение, прежде чем передавать его в SQLConnect. Спасибо PaulMcKenz ie.


    SQLWCHAR name [] = L"db1";
    
    rc = SQLConnect( hdbc,     /* Connection handle */
        name,                  /* The ODBC DSN definition */
        SQL_NTS,               /* This is a null-terminated string */
        NULL,                  /* No username required */
        0,                     /* This is a null-terminated string */
        NULL,                  /* No password required */
        0);                    /* This is a null-terminated string */

1 Ответ

0 голосов
/ 21 июня 2020

Это не будет делать то, что вы думаете:

(SQLWCHAR*)"db1",

Если SQLWCHAR* является указателем на широкий символ, то приведение неширокого строкового литерала не приведет к желаемым результатам, поскольку приведение не приведет к волшебному преобразованию неширокого строкового литерала в широкую строку. Функция ODB C не работает из-за того, что строка "db1" оказывается некорректной, когда функция получает строку.

Надлежащий способ справиться с этим - сначала заставить код скомпилироваться без приведения типа строки к типу строки. Приведение строковых типов является признаком того, что что-то может go неправильно. Используйте строковый тип, который требуется функции.

Это касается любого приложения - если вы приводите строковые типы, вам лучше точно знать, что вы делаете, поскольку вы можете обойти безопасность типов C ++, выдача приведения в стиле C для подавления ошибки компилятора.

В этом случае тип строки SQLWCHAR, таким образом создается строка (в данном случае изменяемая, поскольку это не const указатель) можно сделать:

SQLWCHAR name [] = L"db1";

и тогда функции не потребуется приведение ко второму аргументу:

rc = SQLConnect( hdbc,     /* Connection handle */
    name,                  /* The ODBC DSN definition */
    SQL_NTS,               /* This is a null-terminated string */
    NULL,                  /* No username required */
    0,                     /* This is a null-terminated string */
    NULL,                  /* No password required */
    0);          
...