Добрый вечер. У меня есть программа в которой я подключаюсь к MS SQL Server, затем проверяю скриптом существование нужной мне БД и если её нет, то она этим же скриптом создаёт БД и нужную таблицу в ней. Вот код процедуры подключения и скрипта: | Код | void CDBManager::Init(const std::string &stDBName, const std::string &stDBPath) // stDBName - имя моей БД, stDBPath - путь к фалайм БД на сервере { // COM initialization CoInitialize(NULL);
m_pConn.CreateInstance(__uuidof(Connection)); // Соберём строку подключения std::string stConnection = "Provider=SQLOLEDB.1;Persist Security Info=False;"; stConnection = stConnection + "User ID=" + g_Settings.GetSSUserName() + ";"; stConnection = stConnection + "Password=" + g_Settings.GetSSPasswd() + ";"; stConnection = stConnection + "Initial Catalog=master;"; stConnection = stConnection + "Data Source=" + g_Settings.GetSSAddress(); m_pConn->Open(_bstr_t(stConnection.c_str()), _bstr_t(""), _bstr_t(""), adModeUnknown);
////////////////////////////////////////////////////////////////////////// TCHAR *pszPreparedQuery = NULL; TCHAR *pszRawQuery = NULL;
// Прочитаем скрипт из файла pszRawQuery = GetQueryFromFile(DB_INIT_SCRIPT); if(pszRawQuery) { pszPreparedQuery = new TCHAR[lstrlen(pszRawQuery) + 256]; memset(pszPreparedQuery, 0, lstrlen(pszRawQuery) + 256);
// Подставим в "сырой" запрос имя БД и путь к ней на сервере _snprintf(pszPreparedQuery, lstrlen(pszRawQuery) + 256, pszRawQuery, stDBName.c_str(), stDBPath.c_str());
// Если вылетит исключение, то строка похерится сама... std::string stQuery = pszPreparedQuery;
KILL_ARR(pszRawQuery); KILL_ARR(pszPreparedQuery);
// Выполним запрос на сервере m_pConn->Execute((_bstr_t)stQuery.c_str(), &vtMissing, adCmdText); } else { throw(_S("Не могу найти файл: " << DB_INIT_SCRIPT)); } }
|
Скрипт: | Код | -- v1.0
declare @db_name nvarchar (128), -- Имя БД на сервере (SiteName) @db_path nvarchar (128) -- Путь к БД на диске сервера
set @db_name = '%s' set @db_path = '%s'
-- Проверяем существует ли БД на сервере if((select count(*) from INFORMATION_SCHEMA.SCHEMATA where CATALOG_NAME = @db_name) < 1) begin -- "Сбилдим" запрос на создание новой БД declare @exec_str nvarchar (460) set @exec_str = 'CREATE DATABASE ' + quotename(@db_name, '[') + ' ON PRIMARY (NAME = ''' + @db_name + '_Data'',' + 'FILENAME = ''' + @db_path + @db_name + '_Data.mdf'' ,' + 'SIZE = 100,' + 'FILEGROWTH = 10%)' + ' LOG ON ' + '(NAME = ''' + @db_name + '_Log'',' + 'FILENAME = ''' + @db_path + @db_name + '_Log.ldf'',' + 'SIZE = 100,' + 'FILEGROWTH = 10%)'
-- Выполним запрос exec(@exec_str) -- Добавим таблицы set @exec_str = + 'USE ' + quotename(@db_name, '[') + 'CREATE TABLE aux_observation' + '(' + 'dt DATETIME NOT NULL DEFAULT ''0000-00-00 00:00:00'',' + 'call_dt DATETIME NOT NULL DEFAULT ''0000-00-00 00:00:00'',' + 'cause VARCHAR(16),' + 'user_data VARCHAR(512)' + ')' -- Выполним запрос exec(@exec_str) end
|
Потом я пытаюсь добавить данные в созданную таблицу: | Код | // Откроем набор данных при первом вызове метода if((m_pObsrvRS == NULL) || (m_pObsrvRS->State & adStateOpen) != adStateOpen) { m_pObsrvRS.CreateInstance(__uuidof(Recordset)); m_pObsrvRS->CursorType = adOpenStatic; // Откроем таблицу aux_observation m_pObsrvRS->CursorLocation = adUseClient; std::string stFullDBName = g_Settings.GetSiteName(); stFullDBName += ".dbo.aux_observation"; m_pObsrvRS->Open((_bstr_t)stFullDBName.c_str(), (IDispatch *)m_pConn, adOpenKeyset, adLockOptimistic, adCmdTable); }
// Пытаемся добавить данные FieldsPtr flds = m_pObsrvRS->Fields; m_pObsrvRS->AddNew(); flds->Item[L"dt"]->Value = (_variant_t)dt; flds->Item[L"call_dt"]->Value = (_variant_t)call_dt;
....
flds->Item[L"cause"]->Value = (_bstr_t)cause.c_str(); flds->Item[L"user_data"]->Value = (_bstr_t)user_data.c_str(); m_pObsrvRS->Update();
|
Так вот! При вызове m_pObsrvRS->AddNew(); вылетает исключение: Не удается найти объект в семействе, соответствующий требуемому имени или порядковому номеру.Почему???
|