Соединение с SQL Server c ++ - PullRequest
       16

Соединение с SQL Server c ++

0 голосов
/ 27 ноября 2018

У меня проблемы с подключением к моей локальной базе данных SQL Server Express.Я довольно новичок в c ++ и хотел попробовать возиться с "простыми" подключениями к серверу, чтобы возиться с БД.Но у меня есть две основные ошибки, которые я продолжаю получать и не понял, я верю, что все в бэкэнде настроено правильно (т.е. пользователи сервера / логины и доступность), вот код, который я имею atm:

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

using namespace std;

void showSQLError(SQLCHAR desc[1024], unsigned int handleType, const     SQLHANDLE& handle)
{
SQLCHAR SQLState[1024];
SQLCHAR message[1024];
if (SQL_SUCCESS == SQLGetDiagRec(handleType, handle, 1, SQLState, NULL, message, 1024, NULL))
    // Returns the current values of multiple fields of a diagnostic record that contains error, warning, and status information
    cout << "At Point:" << desc << endl;
    cout << "SQL driver message: " << message << "\nSQL state: " << SQLState << "." << endl;
}

int main()
{

cout << "Hello world" << endl;
SQLHANDLE SQLEnvHandle = NULL;
SQLHANDLE SQLConnectionHandle = NULL;
SQLHANDLE SQLStatementHandle = NULL;
SQLRETURN retCode = 0;
//desc
SQLCHAR noData[1024] = "SQL_NO_DATA\n";
SQLCHAR invalidHandle[1024] = "SQL_INVALID_HANDLE\n";
SQLCHAR error[1024] = "SQL_ERROR\n";
SQLCHAR success[1024] = "Connection succesful";

char SQLQuery[] = "SELECT * FROM roster";

do {
    if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &SQLEnvHandle))
        // Allocates the environment
        break;

    if (SQL_SUCCESS != SQLSetEnvAttr(SQLEnvHandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0))
        // Sets attributes that govern aspects of environments
        break;

    if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_DBC, SQLEnvHandle, &SQLConnectionHandle))
        // Allocates the connection
        break;

    if (SQL_SUCCESS != SQLSetConnectAttr(SQLConnectionHandle, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0))
        // Sets attributes that govern aspects of connections
        break;

    SQLCHAR retConString[1024]; // Conection string
    switch (SQLDriverConnect(SQLConnectionHandle, NULL, (SQLCHAR*)"DRIVER={SQL Server Native Client 11.0}; SERVER=MYPC\SQLEXPRESS, 1433; DATABASE=MYdb; UID=myID; PWD=myPWD ", SQL_NTS, retConString, 1024, NULL, SQL_DRIVER_NOPROMPT)) {
        // Establishes connections to a driver and a data source
    case SQL_SUCCESS:
        break;
    case SQL_SUCCESS_WITH_INFO:
        break;
    case SQL_NO_DATA_FOUND:
        showSQLError(noData , SQL_HANDLE_DBC, SQLConnectionHandle);
        retCode = -1;
        break;
    case SQL_INVALID_HANDLE:
        showSQLError(invalidHandle, SQL_HANDLE_DBC, SQLConnectionHandle);
        retCode = -1;
        break;
    case SQL_ERROR:

        showSQLError(error, SQL_HANDLE_DBC, SQLConnectionHandle);
        retCode = -1;
        break;
    default:
        break;
    }

    if (retCode == -1)
        break;

    if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, SQLConnectionHandle, &SQLStatementHandle))
        // Allocates the statement
        break;

    if (SQL_SUCCESS != SQLExecDirect(SQLStatementHandle, (SQLCHAR*)SQLQuery, SQL_NTS)) {
        // Executes a preparable statement
        showSQLError(success, SQL_HANDLE_STMT, SQLStatementHandle);
        break;
    }
    else {
        char name[256];
        int age;
        while (SQLFetch(SQLStatementHandle) == SQL_SUCCESS) {
            // Fetches the next rowset of data from the result
            SQLGetData(SQLStatementHandle, 1, SQL_C_DEFAULT, &name, sizeof(name), NULL);
            SQLGetData(SQLStatementHandle, 2, SQL_C_DEFAULT, &age, sizeof(age), NULL);
            // Retrieves data for a single column in the result set
            cout << name << " " << age << endl;
        }
    }
} while (FALSE);

SQLFreeHandle(SQL_HANDLE_STMT, SQLStatementHandle);
SQLDisconnect(SQLConnectionHandle);
SQLFreeHandle(SQL_HANDLE_DBC, SQLConnectionHandle);
SQLFreeHandle(SQL_HANDLE_ENV, SQLEnvHandle);
// Frees the resources and disconnects

getchar();
}

поэтому моя первоначальная ошибка с приведенным выше кодом: В точке: SQL_ERROR

Сообщение драйвера SQL: [Microsoft] [Собственный клиент SQL Server 11.0] Поставщик TCP: такой хост не известен.

SQLсостояние: 08001.

И если я изменю строку подключения на:

SQLDriverConnect(SQLConnectionHandle, NULL, (SQLCHAR*)"DRIVER={SQL Server         
 Native Client 11.0}; SERVER=MYPC\\SQLEXPRESS, 1433; DATABASE=MYdb; 
UID=myID; PWD=myPWD ", SQL_NTS, retConString, 1024, NULL, SQL_DRIVER_NOPROMPT)) 

ПРИМЕЧАНИЕ: добавленное '\' в строке SERVER я получаю: В точке: SQL_ERROR

Сообщение драйвера SQL: [Microsoft] [Собственный клиент SQL Server 11.0] Поставщик TCP: не удалось установить соединение, поскольку целевая машина активно отказала ему.

Состояние SQL: 08001.

IПоверьте, что это правильно, но неясно, почему будет отказано.Я правильно (предположительно) настроил все разрешения и учетные записи для сервера, если только мой подход не был прямо неверным.Где / будет ли мой локальный сервер отказывать в моей попытке подключения?

1 Ответ

0 голосов
/ 27 ноября 2018

Я никогда не видел имя экземпляра типа "MYPC \ SQLEXPRESS, 14.0".Почти наверняка это должен быть просто «MYPC \ SQLEXPRESS», а если это на самом деле «MYPC \ SQLEXPRESS, 14.0», его необходимо содержать в {} так, как имя драйвера.

Я предлагаю вам использоватьКоманда «sqlcmd -L» (установите ее из https://www.microsoft.com/en-us/download/details.aspx?id=53591, если у вас ее еще нет) и используйте одно из возвращаемых имен экземпляров.

Преимущество sqlcmd перед другими методами вывода спискаЯ знаю, что sqlcmd использует ODBC, и поэтому вы получите имя, которое готов использовать драйвер ODBC для SQL Server.

...