吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 633|回复: 9
收起左侧

[求助] C++ 一个SQL连接附加数据库读取本地配置文件问题

[复制链接]
16200 发表于 2023-11-27 16:47
具体实现 是运行代码后, 自动连接SQLSERVER 这一步已经实现了,,, 然后就是附加MDF数据库   读取本地 配置文件下名称 路径=D:\\Mud2     数据库实际是在D:\\Mud2\\Data 这个目录下  由于 Data是固定得 所以我想把前面路径设置可修改的 后面采用拼接DATA 起来, 但是不管怎么设置都是找不到。 搞不明白到底是问题出在哪里。 有大神帮我看看这串代码吗?
CONFIG 配置文件内容
路径=D:\\Mud2
计算机名称=DESKTOP-5A5123EW
SQLserver_user=SA
SQLserver=111114123asdqwe


#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <locale>

int main() {
    SQLHANDLE henv; // Environment
    SQLHANDLE hdbc; // Connection
    SQLRETURN retcode;
    // Allocate environment handle
    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
    SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);

    std::locale::global(std::locale("")); // 设置全局区域设置

    // Read configuration from file
    std::wifstream configFile("config.txt"); // 使用wifstream读取宽字符
    if (!configFile.is_open()) {
        std::wcout << L"无法打开配置文件" << std::endl;
        return 1;
    }

    std::wstring computerName, sqlServerUser, sqlServerPassword, dataPath;
    std::wstring line;
    while (std::getline(configFile, line)) {
        if (line.find(L"计算机名称=") != std::wstring::npos) {
            computerName = line.substr(line.find(L"=") + 1);
        }
        else if (line.find(L"SQLserver_user=") != std::wstring::npos) {
            sqlServerUser = line.substr(line.find(L"=") + 1);
        }
        else if (line.find(L"SQLserver=") != std::wstring::npos) {
            sqlServerPassword = line.substr(line.find(L"=") + 1);
        }
        else if (line.find(L"路径=") != std::wstring::npos) {
            dataPath = line.substr(line.find(L"=") + 1);
            dataPath + L"\\Data\\"; // 确保路径末尾有分隔符
        }
    }
    configFile.close();

    // Allocate connection handle
    SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

    // Connect to the SQL Server
    std::wstring connectionString = L"DRIVER={SQL Server};SERVER=" + std::wstring(computerName.begin(), computerName.end())
        + L";DATABASE=master;UID=" + std::wstring(sqlServerUser.begin(), sqlServerUser.end())
        + L";PWD=" + std::wstring(sqlServerPassword.begin(), sqlServerPassword.end());
    retcode = SQLDriverConnect(hdbc, NULL, (SQLWCHAR*)connectionString.c_str(), SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);

    if (SQL_SUCCEEDED(retcode)) {
        std::cout << "成功连接到 SQL Server" << std::endl;

        // Attach MDF data files
        std::vector<std::wstring> mdfFiles = { L"Account", L"Game", L"Manage", L"Res" };
        SQLHANDLE hstmt;  // Statement
        for (const auto& mdf : mdfFiles) {
            std::wstring mdfFilePath = std::wstring(dataPath.begin(), dataPath.end()) + L"\\" + mdf + L".mdf";
            std::wstring databaseName = mdf;

            retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);  // Allocate statement handle
            if (SQL_SUCCEEDED(retcode)) {
                std::wstring attachQuery = L"CREATE DATABASE " + databaseName + L" ON (FILENAME = '" + mdfFilePath + L"') FOR ATTACH";

                retcode = SQLExecDirect(hstmt, (SQLWCHAR*)attachQuery.c_str(), SQL_NTS);

                if (SQL_SUCCEEDED(retcode)) {
                    std::wcout << L"MDF 数据文件 " << mdfFilePath << L" 成功附加为数据库 " << databaseName << std::endl;
                }
                else {
                    SQLWCHAR sqlState[6], errMsg[SQL_MAX_MESSAGE_LENGTH];
                    SQLINTEGER nativeError;
                    SQLSMALLINT textLength;

                    SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, 1, sqlState, &nativeError, errMsg, SQL_MAX_MESSAGE_LENGTH, &textLength);
                    std::wcout << L"无法附加 MDF 数据文件 " << mdfFilePath << L" 为数据库 " << databaseName << std::endl;
                    std::wcout << L"错误信息:" << errMsg << std::endl;
                }

                SQLFreeHandle(SQL_HANDLE_STMT, hstmt);  // Free statement handle
            }
        }
    }
    else {
        std::cout << "无法连接到 SQL Server" << std::endl;
    }

    // Disconnect and free handles
    SQLDisconnect(hdbc);
    SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
    SQLFreeHandle(SQL_HANDLE_ENV, henv);

    return 0;
}

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

jyjjf 发表于 2023-11-27 16:58
运行管理员权限问题?
 楼主| 16200 发表于 2023-11-27 17:00
史前小虫 发表于 2023-11-27 17:06
else if (line.find(L"路径=") != std::wstring::npos) {
    dataPath = line.substr(line.find(L"=") + 1);
    dataPath + L"\\Data\\"; // 确保路径末尾有分隔符
}
将 L"\\Data\\" 拼接到 dataPath,但实际上这行代码并没有改变 dataPath 的值,
因为 dataPath + L"\\Data\\"; 这个表达式计算出来的新字符串并没有被赋值给任何变量。
dataPath = dataPath + L"\\Data\\";或者dataPath += L"\\Data\\";
Eaglecad 发表于 2023-11-27 17:22
代码问题;dataPath + L"\\Data\\"; // 确保路径末尾有分隔符 这句 少了  等号 应该是 dataPath += L"\\Data\\"; // 确保路径末尾有分隔符
vscos 发表于 2023-11-27 18:53
配置文件里的目录符不能用\\这样的双斜扛,改单个看看
 楼主| 16200 发表于 2023-11-27 22:02
Eaglecad 发表于 2023-11-27 17:22
代码问题;dataPath + L"\\Data\\"; // 确保路径末尾有分隔符 这句 少了  等号 应该是 dataPath += L"\\Dat ...

按照这个改 也是读取不到。 如果用绝对路径 就可以读取到。。。
 楼主| 16200 发表于 2023-11-27 22:03
史前小虫 发表于 2023-11-27 17:06
else if (line.find(L"路径=") != std::wstring::npos) {
    dataPath = line.substr(line.find(L"=") +  ...

两种方式我都试了,也是读取不到。  如果是因为 管理员权限  会读取到文件 然后返回 拒绝5 是没权限。 这个是直接读取不到路径
Eaglecad 发表于 2023-11-27 23:02
我按你上面写的,就改了那一处,是可以读取到结果的。你那还不行,可能是以下几个原因
1.配置文件路径问题,比如运行程序在debug目录,配置文件在源代码目录。
2.配置文件,编码格式与开发环境编码格式不一致问题。文件流是宽字节,配置文件最好是gbk
3.读取配置非当前所示文件内容。
 楼主| 16200 发表于 2023-11-28 11:43
Eaglecad 发表于 2023-11-27 23:02
我按你上面写的,就改了那一处,是可以读取到结果的。你那还不行,可能是以下几个原因
1.配置文件路径问题 ...

  好的。谢谢 是编码问题
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 18:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表