Прямые запросы к SQL серверу. Как то возникла ситуация, когда в справочник, с включенной проверкой на уникальность кода, из вне приходят элементы с такими же кодами. Отключать проверку нельзя. Пришлось делать затычку.
Подключение к SQL в общем то широко описано:
Код 1C v 8.х Функция Подключение(Сервер,БД)
cnn = Новый COMОбъект("ADODB.Connection");
cnn.ConnectionTimeOut = 0;
cnn.CommandTimeOut = 0;
cnn.connectionString = "SERVER="+Сервер+"; Database="+БД+"; DRIVER=SQL Server; UID=sa; PWD=*****;";
cnn.Open();
if cnn.State()=0 then
Сообщить("Не удалось соединиться с сервером");
cnn = 0;
Возврат Ложь;
endif;
cnn.Execute("SET NOCOUNT ON");
Возврат cnn;
КонецФункции
Сервер и БД можно получить и программно, но муторно. Эти данные можно взять из свойств БД на сервере 1С.
Название таблицы и полей в SQL можно получить с помощью команды 1С:
Цитата Глобальный контекст
ПолучитьСтруктуруХраненияБазыДанных (GetDBStorageStructureInfo)
Синтаксис:
ПолучитьСтруктуруХраненияБазыДанных(<Объекты метаданных>, <Имена базы данных>)
Параметры:
<Объекты метаданных> (необязательный)
Тип: Массив. Массив имен объектов метаданных или массив объектов метаданных, для которых требуется получить структуру таблиц базы данных.
<Имена базы данных> (необязательный)
Тип: Булево. Определяет, в каких терминах выдается информация о структуре хранения.
Истина - в терминах СУБД
Ложь - в терминах SDBL.
Значение по умолчанию: Ложь
Возвращаемое значение:
Тип: ТаблицаЗначений. Возвращает таблицу значений с описаниями структуры таблиц, индексов и полей базы данных в терминах SDBL или используемой СУБД, в зависимости от значения параметра "Имена базы данных".
Если параметр не используется, то возвращаемая таблица значений содержит информацию о структуре таблиц базы данных всех объектов метаданных.
Таблица значений включает следующие колонки:
ИмяТаблицыХранения(StorageTableName) – имя таблицы SDBL или базы данных;
ИмяТаблицы(TableName) – имя таблицы в терминах языка запросов (для тех у кого оно есть);
Метаданные(Metadata) – полное имя объекта метаданных;
...
Дальше нам нужно новый элемент справочника все ж таки записать, ну например :
Код 1C v 8.х
Попытка
спр. Записать( ) ;
Исключение
Сообщить( "Не уникальный код " + стр. Код+ " у элемента " + стр. Наименование) ;
Спр. УстановитьНовыйКод( ) ;
Спр. Записать( ) ;
КонецПопытки ;
Все, делаем подмену.
Код 1C v 8.х подключение= Подключение( Сервер, База) ;
ТекстЗапроса= "UPDATE Номенклатура
|SET Номенклатура._Code=" + Формат( КодНужный, "ЧГ=0" ) + "
|FROM _Reference57 AS Номенклатура
|WHERE (CAST(Номенклатура._Folder AS int)=1)
|AND (Номенклатура._Code=" + Формат( Спр. Код, "ЧГ=0" ) + ")
|" ;
подключение. Execute( ТекстЗапроса) ;
Сообщить( "Код " + КодБыл+ " подменен на " + КодНужный) ;
Категория:
Запросы Прямое подключение к сторонним Базам Данных Иногда необходимо подключиться к другим (не 1С-ным) БД на том же SQL.
Вот примерный код такого подключения:
Код 1C v 8.х Connection = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения = "Provider=SQLOLEDB.1;Password=" + Здесь пароль доступа + ";Persist Security Info=True;User ID=" + Здесь имя пользователя + ";Initial Catalog=" + Здесь имя БД + "; Data Source=" + Здесь имя сервера + ";";
//Ну и выполним какой-нибудь запрос с обходом:
Результат = Новый COMОбъект("ADODB.Command");
Результат.ActiveConnection = Connection; // работаем через это соединение
Результат.CommandTimeOut = Connection.CommandTimeOut ; // таков тайм-аут
Результат.CommandType = "adCmdText"; // исполняем в точности процедуру
Результат.CommandText = " S_elect name as Наименование
| FROM
| dbo.sysobjects'";
Выборка = Результат.Execute(); // выполняем процедуру
Пока Выборка.Eof() = 0 Цикл
Сообщить(Выборка.Fields("Наименование").Value);
Выборка.MoveNext();
КонецЦикла;
Категория:
COM-объекты, WMI, WSH Создание и работа с БД MySQL из 1С Появилась необходимость выложить часть данных из 1С в открытый доступ большому числу пользователей.
Что бы не нарушать условий лицензирования и обеспечить безопасность данных, было принято решение развернуть новую базу на MySQL. Так как особо модерировать ее никто не хочет, пришлось сделать управление MySQL-ной БД из 1С, и начал с создания структуры БД. Итак:
Создаем 2 справочника неирархических, один подчинен другому.
а.
Таблицы
б.
Колонки
Таблицы - реквизиты:
Автокод - Булево (Определяет необходимость нумеровать запись уникальным кодом, или отдать нумерование на откуп MySQL)
Таблицы - колонки:
ТипДанных - Число (в коде определим тип хранящихся данных по числу)
Длина - Число (длина хранящихся данных)
МожетБытьНоль - булево (может ли хранится пустое значение)
Связь - СсылкаНа таблицу (С которой есть связь все к одному)
Заполняем значениями справочники...
Теперь подключаемся:
Код 1C v 8.х Connection = Новый COMОбъект( "ADODB.Connection" ) ;
СтрокаПодключения = "DRIVER={MySQL ODBC 5.1 Driver};OPTION=3;DATABASE=" + константы. lk_БД. Получить( ) + ";PWD=" + константы. lk_Пароль. Получить( ) + ";PORT=3306;SERVER=" + константы. lk_Сервер. Получить( ) + ";UID=" + константы. lk_Пользователь. Получить( ) + ";" ;
Connection. Open( СокрЛП( СтрокаПодключения) ) ;
Сначала удалим таблицы если они есть:
Код 1C v 8.х Результат = Новый COMОбъект("ADODB.Command");
Результат.ActiveConnection = Connection; // работаем через это соединение
Результат.CommandTimeOut = Connection.CommandTimeOut ; // таков тайм-аут
Результат.CommandType = "adCmdText";
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Таблицы.Наименование КАК Таблица
| ИЗ
| Справочник.Таблицы КАК Таблицы";
ВыборкаТаблиц = Запрос.Выполнить().Выбрать();
Пока ВыборкаТаблиц.Следующий() Цикл
Результат.CommandText = " D_rop TABLE IF EXISTS " + ВыборкаТаблиц.Таблица + " ;";
Результат.Execute();
КонецЦикла;
Теперь приступим к созданию таблиц БД:
Код 1C v 8.х Запрос = Новый Запрос;
Запрос. Текст = "ВЫБРАТЬ
| Таблицы.Наименование КАК Таблица,
| Колонки.Наименование КАК Колонка,
| Колонки.ТипДанных,
| Колонки.Длина,
| Колонки.МожетБытьНоль,
| Колонки.Связь.Наименование КАК Связь
|ИЗ
| Справочник.Колонки КАК Колонки
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Таблицы КАК Таблицы
| ПО Колонки.Владелец = Таблицы.Ссылка
|
|ИТОГИ ПО
| Таблица" ;
ВыборкаТаблиц = Запрос. Выполнить( ) . Выбрать( ОбходРезультатаЗапроса. ПоГруппировкам) ;
Пока ВыборкаТаблиц. Следующий( ) Цикл
Скрипт = " CREATE TABLE " + ВыборкаТаблиц. Таблица + " ( " + символ( 13 ) +
" " + ПолучитьКолонкуID( ВыборкаТаблиц. Таблица) + " int(11) NOT NULL " + ? ( Справочники. Lk_Таблицы. НайтиПоНаименованию( ВыборкаТаблиц. Таблица) . АвтоКод, "auto_increment" , "" ) + "," + символ( 13 ) ;
Выборка = ВыборкаТаблиц. Выбрать( ) ;
Строчека = "" ;
Ключики = "" ;
Пока Выборка. Следующий( ) цикл
Строчека = Строчека + "`" + Выборка. Колонка + "` " + ПолучитьПродолжениеСкрипта( Выборка. ТипДанных, Выборка. длина, Выборка. МожетБытьНоль) + "," + символ( 13 ) ;
ЕСли ЗначениеЗаполнено( Выборка. Связь) Тогда
Ключики = Ключики + ", KEY `FK_" + ВыборкаТаблиц. Таблица + "-" + Выборка. Колонка + "` (`" + Выборка. Колонка + "`),
| CONSTRAINT `FK_" + ВыборкаТаблиц. Таблица + "-" + Выборка. Колонка + "` FOREIGN KEY (`" + Выборка. Колонка + "`) REFERENCES `" + Выборка. Связь + "` (`" + ПолучитьКолонкуID( Выборка. Связь) + "`)" + Символ( 13 ) ;
КонецЕсли ;
КонецЦикла ;
Скрипт = Скрипт + Строчека;
Скрипт = Скрипт + " PRIMARY KEY (" + ПолучитьКолонкуID( ВыборкаТаблиц. Таблица) + ") " + символ( 13 ) + Ключики +
" ) ENGINE=InnoDB DEFAULT CHARSET=utf8;" ;
Сообщить( "Таблица создана: " + ВыборкаТаблиц. Таблица) ;
Результат. CommandText = скрипт;
Результат. Execute( ) ;
КонецЦикла ;
Connection. Close( ) ;
И под закуску недостающие функции, использованные в основном тексте:
Код 1C v 8.х Функция ПолучитьКолонкуID(зн) экспорт
ПрефиксКончился = Ложь ;
Колонка = "" ;
Для сч = 1 по СтрДлина( зн) Цикл
Символик = Mid( зн, Сч, 1 ) ;
Если ПрефиксКончился Тогда
Колонка = Колонка + Символик;
КонецЕсли ;
Если Символик = "_" Тогда
ПрефиксКончился = Истина ;
КонецЕсли ;
КонецЦикла ;
Если Колонка = "" Тогда
Колонка = зн;
КонецЕсли ;
Колонка = Колонка + "ID" ;
Возврат Колонка;
КонецФункции
Предполагается что название таблиц идут с префиксом например: prefix_NameTable
Код 1C v 8.х Функция ПолучитьПродолжениеСкрипта(ТипД,ДлинаД,Ноль) экспорт
Если ТипД = 1 тогда
Зн = " varchar(" + Строка( ДлинаД) + ") " + ? ( Ноль, "null" , "NOT NULL" ) ;
ИначеЕсли ТипД = 2 Тогда
Зн = " int(11) " + ? ( Ноль, "null" , "NOT NULL" ) ;
ИначеЕсли ТипД = 3 Тогда
Зн = " smallint(6) " + ? ( Ноль, "null" , "NOT NULL" ) ;
ИначеЕсли типД = 4 тогда
Зн = " text" ;
ИначеЕсли ТипД = 5 тогда
Зн = " date " + ? ( Ноль, "null" , "NOT NULL" ) ;
ИначеЕсли ТипД = 6 Тогда
Зн = " bit(1) " + ? ( Ноль, "null" , "NOT NULL" ) ;
ИначеЕсли ТипД = 7 Тогда
Зн = " dateTime " + ? ( Ноль, "null" , "NOT NULL" ) ;
КонецЕсли ;
Возврат Зн;
КонецФункции
Источник Категория:
COM-объекты, WMI, WSH