Имя: Пароль:
1C
 
Перевод Запроса 1С в SQL?
0 Serginio1
 
27.12.10
10:43
Часто приходитс перреводить 1с запрос в SQL для различных задач.С небольшими запросами нет проблем, но хочется сразу перевести.
Простейший преобразователь в голове есть, но может уже ктото решал эту проблему или есть соответствие ключевых слов 1С с SQL. Просто нет времени, но хочется и по быстрому.
1 SnarkHunter
 
27.12.10
10:47
>> но хочется и по быстрому

Без труда не вынешь ... из штанов.
2 mikecool
 
27.12.10
10:48
писать запросы на английском - половину переводить не надо будет
3 toypaul
 
гуру
27.12.10
10:48
в профайлере смотри. не все конечно, но большая часть.
4 Serginio1
 
27.12.10
10:49
Если есть уже какието наработки зачем все писать с нуля?
Хо тя бы соответствие ключевых слов
5 mikecool
 
27.12.10
10:49
(3) под постгри не попадался?
6 Defender aka LINN
 
27.12.10
10:49
(2) Так прикольно потом смотреть на такой говонокод :)
7 mikecool
 
27.12.10
10:49
(4) типа
ВЫБРАТЬ - SELECT ?
8 Defender aka LINN
 
27.12.10
10:52
(4) А что это даст?
9 SnarkHunter
 
27.12.10
10:55
(8)Английские слова выучит
10 Serginio1
 
27.12.10
10:56
(7) Да
(3) Что я там потерялся
(8) Напипишу преобразователь сначала разбив текст на термы,
затем заменить их рускоязычные термы на английскиу,
Найти определения таблиц и псевдонимов 1С и заменить их на реальные и поля по псевдонимам, аналогично рекурсивно пройтись по подзапросам. Задача видится не очень сложной, но требующей время которого нет
11 Serginio1
 
27.12.10
10:57
(2) ну хочется использовать конструктор, который мне очень нравится
12 Fynjy
 
27.12.10
11:02
Кто ищет тот обрящет ... Таких трансляторов полно ...
13 kiruha
 
27.12.10
11:04
(10)
Вы ошибаетесь.
Задача достаточно трудоемкая и не сводится к простому переводу
Нечто аналогичное -
http://www.1cpp.ru/forum/YaBB.pl?num=1285352210
14 Defender aka LINN
 
27.12.10
11:05
(10) Как насчет виртуальных таблиц? Параметров?
15 Serginio1
 
27.12.10
11:07
(13) 8.2 достаточно приближены к SQL и допилка их не сложная.
(12) Спасибо за совет уже давно им воспользовался но не нашел
16 Fynjy
 
27.12.10
11:08
(15) Ну вот к пример ... http://infostart.ru/public/14635/ ...
17 el-gamberro
 
27.12.10
11:08
Это делатся по другому. 1с-вский запрос помещает необходимые данные во временную таблицу.
Запрос SQL выглядит так:

SELECT * FROM #temptable_1c
18 mikecool
 
27.12.10
11:08
(15) запросы в 8.х уже достаточны и допиливать их смысла нет
разве что умудриться хинты вставлять
19 el-gamberro
 
27.12.10
11:10
(18) Смысл есть. К примеру в 1с ких запросах нет простейшего ltrim(rtrim())
20 mikecool
 
27.12.10
11:10
(19) вот только из-за этих двух функций городить огород?
21 Serginio1
 
27.12.10
11:11
(18) Я использую для оптимизации с помощью использования всего арсенала T-SQL, для массовых изменений.
22 mikecool
 
27.12.10
11:11
+20 сказал бы за cast или convert, а так...
23 mikecool
 
27.12.10
11:12
(21) ну, батенька... запросы 1с вообще не предназначены для изменения
24 Ненавижу 1С
 
гуру
27.12.10
11:12
EXISTS нету!
25 el-gamberro
 
27.12.10
11:13
(22) иногда из-за их отсутсвия приходится огород покруче городить))
26 kiruha
 
27.12.10
11:13
(16)
Собственно разве есть что то еще кроме German ?
(15)>>8.2 достаточно приближены к SQL и допилка их не сложная.

Попробуйте для начала, хотя бы перевести "точки" в запросах
Про вспомогательные временные таблицы и оптимизацию промолчу
27 mikecool
 
27.12.10
11:13
(24) ну можно малой кровью заменить
где 1 в (выбрать 1 из ...)
:))
28 Serginio1
 
27.12.10
11:13
(16) Я его уже давно знаю.Там не совсем то что нужно. Нужно получить запрос с нормальными полями, для его дальнейшего изменения.
29 Serginio1
 
27.12.10
11:15
(23) Спасибо, но вместо Select всегда можно подсавить Delete или Update
Или Merge при булках
30 DmitrO
 
27.12.10
11:36
(0)c этой задачей отлично справляется технологический журнал.
Быстро и точно. :)
31 Serginio1
 
27.12.10
11:41
(26) Использую только пакетные запросы.
Смотри (10)
(30) А хочется без лишних телодвижений.
32 DmitrO
 
27.12.10
11:45
(31)Т.е. те телодвижения которые ты планируешь совершить в (10) ты лишними не считаешь? :)
33 Berck
 
27.12.10
11:53
(0) http://infostart.ru/public/14692/
SQLPlus
вот посмотри.
34 Serginio1
 
27.12.10
12:44
(33) Огромнейший респект. Спасибо!!!
Мельком глянул очень понравилось. Там немного допилить добавить псевдонимы полей виртуальные таблицы разбить на подзапросы. Да и поля опционно можно русскими оставлять.
35 PowerBoy
 
27.12.10
12:55
(34) Да не довел я ее до ума - но как то использовать можно.
36 КонецЦикла
 
27.12.10
12:55
1С массу информации обрабатывает в своих кишках, всего не увидеть
Если цель - скорость и некоторые бонусы настоящего T-SQL то имеет смысл на нем и писать :)
37 Serginio1
 
27.12.10
13:05
(35) Да ничего сам потихонечку допилю по необходимости и если нужно тебе скину.
Еще раз большое спасибо за труды!!!
38 Serginio1
 
27.12.10
13:07
(36) Ну хочется использовать удобный конструктор, понимаемые поля, а затем уже этот текст адаптировать под все возможности T-SQL
39 kiruha
 
27.12.10
14:06
Не совсем понял - в SQLPlus виртуальные таблицы реализованы ?
40 Serginio1
 
27.12.10
14:26
(39) Насколько я понял то нет.
Но можно дописать. например для среза последних
Функция СоздатьТекстСрезПоследних(ИменаГрупСтр,ИменаРесурсовСтр,Регистр)
           
       Если ПустаяСтрока(ИменаГрупСтр) Тогда
               ИменаГруп=Новый Массив
               Иначе
           ИменаГруп=ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ИменаГрупСтр,",");
       КонецЕсли;
                     
       ИменаРесурсов=ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ИменаРесурсовСтр,",");
           Массив=Новый Массив;
   Массив.Добавить("РегистрСведений."+Регистр);
  ТЗ = ПолучитьСтруктуруХраненияБазыДанных(Массив,Истина);
   
   СтрТз=Тз.Найти("РегистрСведений."+Регистр,"ИмяТаблицы");
   Поля=ПреобразоватьТзВСтруктуру(СтрТз);
   ИмяПсевдонимаРегистра=Регистр+"СрезПоследних";
           Стр="
   |Select";
   Для каждого Поле из ИменаГруп Цикл
       Стр=Стр+"
   |"+ИмяПсевдонимаРегистра+"."+Поля[Поле]+" as "+Поле+","
КонецЦикла;

Для каждого Поле из ИменаРесурсов Цикл
       Стр=Стр+"
   |"+ИмяПсевдонимаРегистра+"."+Поля[Поле]+" as "+Поле+","
КонецЦикла;

Стр=Лев(Стр,СтрДлина(Стр)-1);
Стр=Стр+"
   |From
   |"+    СтрТз.ИмяТаблицыХранения+" as "+ИмяПсевдонимаРегистра+"
   | Join (Select ";
   
   Для каждого Поле из ИменаГруп Цикл
       Стр=Стр+"
   |"+Поля[Поле]+" as "+Поле+","
  КонецЦикла;

   Стр=Стр+" Max(_PERIOD) as Период
   |From
   |"+    СтрТз.ИмяТаблицыХранения+"
   |where "+Поля.Период+"<=@ТекущаяДата
   |Group By ";
   ЭтоПервый=Истина;
   Для каждого Поле из ИменаГруп Цикл
       Если ЭтоПервый Тогда
           ЭтоПервый=Ложь;
       Стр=Стр+Поля[Поле]
           иначе
       Стр=Стр+","+Поля[Поле]
       КонецЕсли;
   КонецЦикла;
   
   
   Стр=Стр+") as ПоследниеДаты
   |ON ";
   ЭтоПервый=Истина;
   Для каждого Поле из ИменаГруп Цикл
       Если ЭтоПервый Тогда
           ЭтоПервый=Ложь;
           Стр=Стр+"
   |"+Поля[Поле]+" = ПоследниеДаты."+Поле
           Иначе
       Стр=Стр+"
   |and "+Поля[Поле]+" = ПоследниеДаты."+Поле
   КонецЕсли;
КонецЦикла;
Стр=Стр+"
   |and "+ИмяПсевдонимаРегистра+"._PERIOD=ПоследниеДаты.Период;";
   возврат Стр;

       КонецФункции
41 Serginio1
 
27.12.10
17:03
(35) Я обычно соединяюсь виндовую аутентификацию с сервера
Процедура ПолучитьSqlИмяСервераИБазы(Сервер,Порт,ИмяБазы,SqlServer,SqlBaseName)
Соединитель = Новый COMОбъект("V82.COMConnector");
СоединениеСАгентом = Соединитель.ConnectAgent(Сервер);

Кластеры = СоединениеСАгентом.GetClusters();
Кластер = Кластеры.GetValue(Кластеры.GetLowerBound()); // первый кластер
СоединениеСАгентом.Authenticate(Кластер, "", "");
РабочиеПроцессы = СоединениеСАгентом.GetWorkingProcesses(Кластер);
РабочийПроцесс = РабочиеПроцессы.GetValue(РабочиеПроцессы.GetLowerBound()); // первый рабочий процесс
АдресРабочегоПроцесса =
"tcp://" +
РабочийПроцесс.HostName +
":" +
XMLСтрока(РабочийПроцесс.MainPort);
СоединениеСРабочимПроцессом = Соединитель.ConnectWorkingProcess(АдресРабочегоПроцесса);
СоединениеСРабочимПроцессом.AddAuthentication("ADM","161069275");
ИнформационныеБазы = СоединениеСРабочимПроцессом.GetInfoBases();

Для каждого База из ИнформационныеБазы Цикл
   Если Врег(База.Name)=Врег(ИмяБазы) Тогда
       Сообщить(База.DBServerName);
       Сообщить(База.DBName);
       SqlServer=База.DBServerName;
       SqlBaseName=База.DBName;
   КонецЕсли;
   
КонецЦикла;


   КонецПроцедуры
   Функция ПолучитьТекущийСерверИБазу()
       Перем SqlServer,SqlBaseName;
   //  Сообщить(СтрокаСоединенияИнформационнойБазы());
     Массив=ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(СтрЗаменить(СтрокаСоединенияИнформационнойБазы(),"""",""),";");
     Резулт=Новый Структура;
     Для Каждого стр из Массив Цикл
         Если ЗначениеЗаполнено(Стр) Тогда
       КейВалуе=ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(стр,"=");
       Резулт.Вставить(КейВалуе[0],КейВалуе[1])
       КонецЕсли;
   КонецЦикла;
   
   ПолучитьSqlИмяСервераИБазы(Резулт.Srvr,1540,Резулт.Ref,SqlServer,SqlBaseName);
   Резулт.Srvr=SqlServer;
   Резулт.Ref=SqlBaseName;
   возврат Резулт;
КонецФункции

Функция ВыполнитьКомандуSQL(ТекстЗапроса) Экспорт
   ДанныеСервера=ПолучитьТекущийСерверИБазу();

   
ConnectionString ="DRIVER=SQL Server;
|UID=администратор;
|Network=DBMSSOCN;
|LANGUAGE=русский;
|DATABASE="+ДанныеСервера.Ref+";
|WSID="+ДанныеСервера.Srvr+";
|APP=Microsoft® Windows® Operating System;
|Trusted_Connection=Yes;
|SERVER="+ДанныеСервера.Srvr;

//Сообщить(СтрокаСоединенияИнформационнойБазы());
    Connection = Новый COMОбъект("ADODB.Connection");
   //ADO_Recordset = Новый COMОбъект("ADODB.Recordset");
   //ADO_Command = Новый COMОбъект("ADODB.Command");
    // ADO_Connection.
//    Соединение.ConnectionString = "DSN=" + ДСН + ";UID=" + УИД + ";PWD=" + ПВД;  
   Connection.ConnectionString = ConnectionString;
   Connection.CommandTimeOut=0;
   Connection.ConnectionTimeout = 0;
   Connection. CursorLocation= 3;
   Сообщить(Connection.ConnectionString);
   Connection.Open();

Command = Новый COMОбъект("ADODB.Command");
Command.ActiveConnection=Connection;
Command.CommandType = 1;
Command.CommandTimeout=0;

Command.CommandText=ТекстЗапроса;
//RecordSet = Новый COMОбъект("ADODB.RecordSet");
РекордСет=Command.Execute();

Резулт="";
Пока РекордСет<>неопределено Цикл
   Если РекордСет.Fields.Count>0 Тогда
       Поле=РекордСет.Fields(0);
       Стр=Поле.Name+" "+Поле.Value;
       Если ЗначениеЗаполнено(Резулт) тогда
           Резулт=Резулт+"
           |"+Стр
       иначе
           Резулт=Стр;
       КонецЕсли;
   КонецЕсли;
   РекордСет=РекордСет.NextRecordSet();
КонецЦикла;
Сообщить(Резулт);
Возврат  Резулт
КонецФункции
Пользователь не знает, чего он хочет, пока не увидит то, что он получил. Эдвард Йодан