несколько бд: как?
От: gok Россия  
Дата: 13.12.16 23:46
Оценка:
Пользователь пользует некоторый набор баз данных в МS SQL.
Сделал соединение через ODBC DSN, в которой прописано имя базы данных.
Теперь надо извернуться так, чтобы программно переключаться с базы на базу.
MS SQL на доменном сервере, т.е. нужен логин на сервер, потом в MS SQL.

Вопрос про DSN: как он исхитряется не логинится на сервер, а сразу работает с базой данных?

Пробовал программно использовать как то так:
CDatabase thisDb;
CString dbName(_T("МОЙТЕСТ"));
BOOL openRes = thisDb.OpenEx(_T("Driver={SQL Server Native Client 11.0};Server=мойсервер;Database=") + dbName + ("AttachDbFilename=.;Trusted_Connection=No;Uid=") + username + _T(";Pwd=") + pass_word + _T(";"));

а соединение выбрасывает диалог и спрашивает имя-пароль на вход на сервер. Можно ли этого избежать?
МОжно, конечно, создать различных пользователей и винда сама будет подсовывать нужную базу данных для "этого" пользователя в DSN строке.
Только срр, х64, винда

Спасибо!
gok
Re: несколько бд: как?
От: Olaf Россия  
Дата: 14.12.16 06:46
Оценка: +2
Здравствуйте, gok, Вы писали:

gok>Сделал соединение через ODBC DSN, в которой прописано имя базы данных.

gok>Теперь надо извернуться так, чтобы программно переключаться с базы на базу.
gok>MS SQL на доменном сервере, т.е. нужен логин на сервер, потом в MS SQL.

Для доступа к SQL Server необходим логин на самом SQL Server с правами на БД. Причем может использоваться аутентификация как доменная, так и SQL. Не совсем понятно, зачем нужен логин на сервер, а потом MS SQL и о каком сервере идет речь.

gok>Вопрос про DSN: как он исхитряется не логинится на сервер, а сразу работает с базой данных?


А вы настроили DSN на локальный сервер или удаленный? Не указав параметры аутентификации вы смогли подключиться к БД?

gok>Пробовал программно использовать как то так:

gok>
gok>CDatabase thisDb;
gok>CString dbName(_T("МОЙТЕСТ"));
gok>BOOL openRes = thisDb.OpenEx(_T("Driver={SQL Server Native Client 11.0};Server=мойсервер;Database=") + dbName + ("AttachDbFilename=.;Trusted_Connection=No;Uid=") + username + _T(";Pwd=") + pass_word + _T(";"));
gok>

gok>а соединение выбрасывает диалог и спрашивает имя-пароль на вход на сервер. Можно ли этого избежать?

CDatabase — это случайно не класс MFC?
Re[2]: несколько бд: как?
От: gok Россия  
Дата: 14.12.16 21:47
Оценка:
Здравствуйте, Olaf, Вы писали:

O>Здравствуйте, gok, Вы писали:


gok>>Сделал соединение через ODBC DSN, в которой прописано имя базы данных.

gok>>Теперь надо извернуться так, чтобы программно переключаться с базы на базу.
gok>>MS SQL на доменном сервере, т.е. нужен логин на сервер, потом в MS SQL.

O>Для доступа к SQL Server необходим логин на самом SQL Server с правами на БД. Причем может использоваться аутентификация как доменная, так и SQL. Не совсем понятно, зачем нужен логин на сервер, а потом MS SQL и о каком сервере идет речь.

Сама машина, на которой установлен MS SQL подключена к местному домену. Чтобы посмотреть что происходит с таблицами мне надо залогиниться на сервер. А потом открыть MS SQL Manager уже с логином для MS SQL.

gok>>Вопрос про DSN: как он исхитряется не логинится на сервер, а сразу работает с базой данных?


O>А вы настроили DSN на локальный сервер или удаленный? Не указав параметры аутентификации вы смогли подключиться к БД?

Не знаю разницы между локальным и удаленным сервером. При создании DSN я указал название доменного сервера, сразу же создался список доступных баз данных. Да, для соединения с БД указал логин для MS SQL. Тест DSN прошел нормально. Странно как так ODBC не требует аутентификацию на сам доменный сервер, а только в БД.

gok>>Пробовал программно использовать как то так:

gok>>
gok>>CDatabase thisDb;
gok>>CString dbName(_T("МОЙТЕСТ"));
gok>>BOOL openRes = thisDb.OpenEx(_T("Driver={SQL Server Native Client 11.0};Server=мойсервер;Database=") + dbName + ("AttachDbFilename=.;Trusted_Connection=No;Uid=") + username + _T(";Pwd=") + pass_word + _T(";"));
gok>>

gok>>а соединение выбрасывает диалог и спрашивает имя-пароль на вход на сервер. Можно ли этого избежать?

O>CDatabase — это случайно не класс MFC?

Да, это от MFC, приложение довольно старое. Хотелось бы симмитировать строку соединения, которую пользует DSN (без логина в сервер).
Или есть какие-нибудь другие подходы?

Спасибо
gok
Re[3]: несколько бд: как?
От: Olaf Россия  
Дата: 16.12.16 04:16
Оценка: 1 (1) +1
Здравствуйте, gok, Вы писали:

gok>Сама машина, на которой установлен MS SQL подключена к местному домену. Чтобы посмотреть что происходит с таблицами мне надо залогиниться на сервер. А потом открыть MS SQL Manager уже с логином для MS SQL.


Возможно ваш подход имеет право на существование, но на мой взгляд подключение к SQL Server через сервер на котором он хостится лишнее, хотя конечно я не знаю вашей задачи целиком. SQL Server сам выполняет аутентификацию пользователей, поэтому вам достаточно передать учетные данные через строку соединения и выполнить подключение. Если ваша рабочая станция не входит в домен, то вы можете подключаться с использованием SQL Server аутентификации, предварительно создав на самом SQL сервере логин с паролем и доступом к БД. Использование хостинг-сервера для подключения к SQL Server лишняя итерация, на мой взгляд.

gok>Не знаю разницы между локальным и удаленным сервером.


Локальный сервер – экземпляр SQL Server, который установлен на вашем компьютере, локально, соответственно удаленный сервер расположен за пределами вашего компьютера.

gok>При создании DSN я указал название доменного сервера, сразу же создался список доступных баз данных. Да, для соединения с БД указал логин для MS SQL. Тест DSN прошел нормально.


А DSN вы создали на вашем компьютере, или на хостинг сервере, где расположен SQL Server ?

gok>Странно как так ODBC не требует аутентификацию на сам доменный сервер, а только в БД.


Нет ничего странного. ODBC работает с сервером БД, он даже не пытается требовать аутентификацию на доменном сервере, она ему ни к чему. Как я уже сказал выше, SQL Server сам выполняет аутентификацию одним из возможных способов. Для подключения к SQL Server необходимо и достаточно наличие доступа к самому SQL Server. Права доступа к серверу, который хостит SQL Server не нужны.

gok>Да, это от MFC, приложение довольно старое. Хотелось бы симмитировать строку соединения, которую пользует DSN (без логина в сервер).


Согласно документации Microsoft CDatabase::OpenEx, если строка соединения не содержит достаточных сведений для подключения, драйвер открывает окно для получения недостающих данных. Поэтому я бы проверил правильность заполнения переменных username и pass_word и если строка соединения формируется верно, то попробовал бы воспользоваться вторым аргументом в методе OpenEx, который позволяет скрыть диалоговое окно CDatabase::noOdbcDialog.

gok>Или есть какие-нибудь другие подходы?


Я думаю способы есть, но лучше спросить в прикладном форуме по С++. Хотя ваша проблема ни в том каким способом вы подключаетесь. Нужно разобраться с аутентификацией, какие учетные данные вы используете, проверить правильность заполнения строки подключения.
Re[4]: несколько бд: как?
От: gok Россия  
Дата: 16.12.16 16:32
Оценка:
Здравствуйте, Olaf, Вы писали:

O>Здравствуйте, gok, Вы писали:


gok>>Сама машина, на которой установлен MS SQL подключена к местному домену. Чтобы посмотреть что происходит с таблицами мне надо залогиниться на сервер. А потом открыть MS SQL Manager уже с логином для MS SQL.


O>Возможно ваш подход имеет право на существование, но на мой взгляд подключение к SQL Server через сервер на котором он хостится лишнее, хотя конечно я не знаю вашей задачи целиком. SQL Server сам выполняет аутентификацию пользователей, поэтому вам достаточно передать учетные данные через строку соединения и выполнить подключение. Если ваша рабочая станция не входит в домен, то вы можете подключаться с использованием SQL Server аутентификации, предварительно создав на самом SQL сервере логин с паролем и доступом к БД. Использование хостинг-сервера для подключения к SQL Server лишняя итерация, на мой взгляд.


Возвращаясь к строке соединения с SQL Server-ом. Какое имя SQL Server в домене? DSN оперирует именем хостинговой машины, значит это и есть имя SQL Server-a?
BOOL openRes = thisDb.OpenEx(_T("Driver={SQL Server Native Client 11.0};Server=мойХостинг;Database=") + dbName + ("AttachDbFilename=.;Trusted_Connection=No;Uid=") + username + _T(";Pwd=") + pass_word + _T(";"));
Как бы offtop: а если на хостинге 2 разные версии SQL Server установлены (если это вообще возможно)? Как драйвер будет их разруливать?

gok>>Не знаю разницы между локальным и удаленным сервером.

O>Локальный сервер – экземпляр SQL Server, который установлен на вашем компьютере, локально, соответственно удаленный сервер расположен за пределами вашего компьютера.
а, значит мой SQL Server удаленный, в том же домене что и моя рабочая станция.

gok>>При создании DSN я указал название доменного сервера, сразу же создался список доступных баз данных. Да, для соединения с БД указал логин для MS SQL. Тест DSN прошел нормально.

O>А DSN вы создали на вашем компьютере, или на хостинг сервере, где расположен SQL Server ?
На моем компьютере. DSN "привязан" к БД, вот этого надо избежать. DSN выплыл как образец для подражания, в коде его не должно быть.

gok>>Странно как так ODBC не требует аутентификацию на сам доменный сервер, а только в БД.

O>Нет ничего странного. ODBC работает с сервером БД, он даже не пытается требовать аутентификацию на доменном сервере, она ему ни к чему. Как я уже сказал выше, SQL Server сам выполняет аутентификацию одним из возможных способов. Для подключения к SQL Server необходимо и достаточно наличие доступа к самому SQL Server. Права доступа к серверу, который хостит SQL Server не нужны.
Очень обещающе! Буду пробиваться через строку соединения!

gok>>Да, это от MFC, приложение довольно старое. Хотелось бы симмитировать строку соединения, которую пользует DSN (без логина в сервер).

O>Согласно документации Microsoft CDatabase::OpenEx, если строка соединения не содержит достаточных сведений для подключения, драйвер открывает окно для получения недостающих данных. Поэтому я бы проверил правильность заполнения переменных username и pass_word и если строка соединения формируется верно, то попробовал бы воспользоваться вторым аргументом в методе OpenEx, который позволяет скрыть диалоговое окно CDatabase::noOdbcDialog.
Логин нормальный. Попробую с отключением диалога.

gok>>Или есть какие-нибудь другие подходы?

O>Я думаю способы есть, но лучше спросить в прикладном форуме по С++. Хотя ваша проблема ни в том каким способом вы подключаетесь. Нужно разобраться с аутентификацией, какие учетные данные вы используете, проверить правильность заполнения строки подключения.
Согласен, добиваю MFC строку соединения
gok
Re[5]: несколько бд: как?
От: Olaf Россия  
Дата: 19.12.16 06:13
Оценка:
Здравствуйте, gok, Вы писали:

gok>Возвращаясь к строке соединения с SQL Server-ом. Какое имя SQL Server в домене? DSN оперирует именем хостинговой машины, значит это и есть имя SQL Server-a?

gok>BOOL openRes = thisDb.OpenEx(_T("Driver={SQL Server Native Client 11.0};Server=мойХостинг;Database=") + dbName + ("AttachDbFilename=.;Trusted_Connection=No;Uid=") + username + _T(";Pwd=") + pass_word + _T(";"));
gok>Как бы offtop: а если на хостинге 2 разные версии SQL Server установлены (если это вообще возможно)? Как драйвер будет их разруливать?

На одном компьютере может быть установлено несколько SQL серверов, точнее служб sqlservr.exe Каждая копия файла является экземпляром SQL сервера и работает независимо от наличия или отсутствия других. Экземпляр по умолчанию не имеет имени, поэтому обращение к нему идет по имени (IP адресу) сервера, например "мойХостинг". Только один экземпляр может быть экземпляром по умолчанию. Всем последующим экземплярам при установке присваивается имя, которое используется в строке подключения, например "мойХостинг\ЭкземплярXX". Такие экземпляры называются именованными и их может быть несколько.

Если вы не указываете имя, значит у вас экземпляр по умолчанию.

gok>На моем компьютере. DSN "привязан" к БД, вот этого надо избежать. DSN выплыл как образец для подражания, в коде его не должно быть.


Вы можете использовать строку подключения, причем часть данных хранится в конфигурационном файле приложения, часть запрашивается у пользователя через диалоги. Здесь уже в зависимости от задачи.

Важно понимать какую аутентификацию вы используете в строке подключения – WINDOWS или SQL. Вот здесь есть Примеры строк подключения, которые показывают отличие Standard security от Trusted Connection.

Забыл сказать в прошлый раз – не совсем понятно, зачем для удаленного сервера вы используете свойство AttachDbFilename = . Ошибки при подключении возможно не будет, но и каких-то действий со стороны SQL сервера не последует.
Re[6]: несколько бд: как?
От: gok Россия  
Дата: 19.12.16 20:52
Оценка:
Здравствуйте, Olaf, Вы писали:

O>Здравствуйте, gok, Вы писали:


gok>>Возвращаясь к строке соединения с SQL Server-ом. Какое имя SQL Server в домене? DSN оперирует именем хостинговой машины, значит это и есть имя SQL Server-a?

gok>>BOOL openRes = thisDb.OpenEx(_T("Driver={SQL Server Native Client 11.0};Server=мойХостинг;Database=") + dbName + ("AttachDbFilename=.;Trusted_Connection=No;Uid=") + username + _T(";Pwd=") + pass_word + _T(";"));
gok>>Как бы offtop: а если на хостинге 2 разные версии SQL Server установлены (если это вообще возможно)? Как драйвер будет их разруливать?

O>На одном компьютере может быть установлено несколько SQL серверов, точнее служб sqlservr.exe Каждая копия файла является экземпляром SQL сервера и работает независимо от наличия или отсутствия других. Экземпляр по умолчанию не имеет имени, поэтому обращение к нему идет по имени (IP адресу) сервера, например "мойХостинг". Только один экземпляр может быть экземпляром по умолчанию. Всем последующим экземплярам при установке присваивается имя, которое используется в строке подключения, например "мойХостинг\ЭкземплярXX". Такие экземпляры называются именованными и их может быть несколько.


O>Если вы не указываете имя, значит у вас экземпляр по умолчанию.

!!

gok>>На моем компьютере. DSN "привязан" к БД, вот этого надо избежать. DSN выплыл как образец для подражания, в коде его не должно быть.


O>Вы можете использовать строку подключения, причем часть данных хранится в конфигурационном файле приложения, часть запрашивается у пользователя через диалоги. Здесь уже в зависимости от задачи.


O>Важно понимать какую аутентификацию вы используете в строке подключения – WINDOWS или SQL. Вот здесь есть Примеры строк подключения, которые показывают отличие Standard security от Trusted Connection.


O>Забыл сказать в прошлый раз – не совсем понятно, зачем для удаленного сервера вы используете свойство AttachDbFilename = . Ошибки при подключении возможно не будет, но и каких-то действий со стороны SQL сервера не последует.


Перепробовал все возможные строки соединения, постоянно высвечивается диалог с предложением выбрать DSN. При попытке отключить его в опциях CDatabase.OpenEx(..) приложение крэшется.
В этом проекте: используется CDatabase, но в 32-битном варианте. Попытка переключиться на х64 выдала ошибку: Database error: Data source name not found and no default driver specified.
Что указывает на несовместимость х64 с ODBC драйверами (windows 10)! Какой DSN хитрый, как он соединяется? Или это только обертка для 32-битного драйвера?
Пробую законнектиться с х64 драйвером
gok
Re[7]: несколько бд: как?
От: Olaf Россия  
Дата: 20.12.16 05:14
Оценка:
Здравствуйте, gok, Вы писали:

gok>Перепробовал все возможные строки соединения, постоянно высвечивается диалог с предложением выбрать DSN. При попытке отключить его в опциях CDatabase.OpenEx(..) приложение крэшется.


Все верно, если вы гасите диалог, то у вас исчезает шанс поправить параметры строки соединения и повторно подключиться к СУБД. CDatabase кидает исключение CDBException, которое нужно отловить и там же кстати можно посмотреть сообщение об ошибке.
try
{
    CDatabase db;
    bool result = db.OpenEx(_T("Driver={SQL Server Native Client 11.0};Server=(localdb)\\MSSQLLocalDB;Database=Demo;Trusted_Connection=No;Uid=ouk;Pwd=1;"), CDatabase::noOdbcDialog);
    if (result)
        OutputDebugString(L"Подключение успешно выполнено!\n");
    else
        OutputDebugString(L"Подключение не выполнено!\n");
}
catch (CDBException* e)
{
    OutputDebugString(e->m_strError);
}

Вот пример строки соединения, с помощью которой мне удалось подключиться к своему локальному серверу с использованием SQL аутентификации. При этом, как и сказано в документации, если каких-то параметров недостаточно или возникает ошибка при подключении, всплывает дополнительно окно для корректировки параметров соединения. У вас отображается ошибка перед тем как всплывает окно с предложением что-либо ввести в случае если вы не гасите диалог?
Отредактировано 20.12.2016 5:22 Olaf . Предыдущая версия .
Re[8]: несколько бд: как?
От: gok Россия  
Дата: 20.12.16 15:24
Оценка:
Здравствуйте, Olaf, Вы писали:

O>Здравствуйте, gok, Вы писали:


gok>>Перепробовал все возможные строки соединения, постоянно высвечивается диалог с предложением выбрать DSN. При попытке отключить его в опциях CDatabase.OpenEx(..) приложение крэшется.


O>Все верно, если вы гасите диалог, то у вас исчезает шанс поправить параметры строки соединения и повторно подключиться к СУБД. CDatabase кидает исключение CDBException, которое нужно отловить и там же кстати можно посмотреть сообщение об ошибке.

O>
O>try
O>{
O>    CDatabase db;
O>    bool result = db.OpenEx(_T("Driver={SQL Server Native Client 11.0};Server=(localdb)\\MSSQLLocalDB;Database=Demo;Trusted_Connection=No;Uid=ouk;Pwd=1;"), CDatabase::noOdbcDialog);
O>    if (result)
O>        OutputDebugString(L"Подключение успешно выполнено!\n");
O>    else
O>        OutputDebugString(L"Подключение не выполнено!\n");
O>}
O>catch (CDBException* e)
O>{
O>    OutputDebugString(e->m_strError);
O>}
O>

O>Вот пример строки соединения, с помощью которой мне удалось подключиться к своему локальному серверу с использованием SQL аутентификации. При этом, как и сказано в документации, если каких-то параметров недостаточно или возникает ошибка при подключении, всплывает дополнительно окно для корректировки параметров соединения. У вас отображается ошибка перед тем как всплывает окно с предложением что-либо ввести в случае если вы не гасите диалог?

Экспериментирую теперь уже с Аксесом, простейший случай!
Для х64 советовали ACE драйвер:
CString sDriver = "Microsoft.ACE.OLEDB.12.0";
В случае пустой DSN, как здесь:
sDsn.Format("PROVIDER=%s;Data Source=%s;Persist Security Info=False;DSN='';",sDriver,sFile);
BOOL result = database.Open(NULL,false,false,sDsn);
бросает исключение:
"Database error: Data source name not found and no default driver specified"
Без DSN в строке соединения выплывает запрос на выбор DSN.
x86 версия работает как часики c этим драйвером: CString sDriver = "MICROSOFT ACCESS DRIVER (*.mdb)";!
У вас какая версия приложения?
gok
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.