Имя: Пароль:
1C
 
SQL Запросы из 1С, ошибка:Операция не допускается, если объект закрыт.
0 ig0z
 
21.04.17
09:13
После добавление временной таблицы и левого соединения к Основному запросу (много строк) начала выскакивать ошибка, указанная в заголовке.
Как-то не понятно почему, до этого использовал временные таблицы не было такого ...
    
    // само левое соединение
    |    -- Отобрать Outcome
    |    LEFT JOIN #MasterTransactionIdForOutcome        AS TraOt ON TraOt.MasterTransactionId    = Operations.MasterTransactionId



    |    -- СОСТАВИТЬ СПИСОК MasterTransactionId С Outcome
    |    IF OBJECT_ID('tempdb..MasterTransactionIdForOutcome') IS NOT NULL DROP TABLE #MasterTransactionIdForOutcome
    |    SELECT DISTINCT TraT.MasterTransactionId
    |    INTO     #MasterTransactionIdForOutcome
    |    FROM ski2db2017.dbo.MasterTransaction         AS Operations
    |        LEFT JOIN ski2db2017.dbo.TransactionDetail AS Tra ON Tra.MasterTransactionId = Operations.MasterTransactionId
    |                AND Tra.SuperAccountIdFrom = 2 AND Tra.SuperAccountIdTo IS NULL
    |            LEFT JOIN ski2db2017.dbo.TransactionDetail AS TraT ON TraT.MasterTransactionId = Tra.MasterTransactionId
    |                    AND TraT.SuperAccountIdFrom <> 2 AND TraT.SuperAccountIdFrom IS NOT NULL
    |                    AND TraT.SuperAccountIdTo = 2
    |    WHERE TraT.MasterTransactionId IS NOT NULL  --Operations.TransTime BETWEEN '20170202' AND '20170203'


RecordSet = Новый COMОбъект("ADODB.RecordSet");
    RecordSet.Open(ТекстЗапроса, Connection);
    
    //перейдём в начало списка
    Если Не RecordSet.EOF Тогда
        RecordSet.MoveFirst();
    КонецЕсли;
    
    
    Попытка
        // для каждой полученной записи        
        Пока Не RecordSet.EOF Цикл     // ТУТ ОШИБКА ВЫЛЕТАТ ОБ Операция не допускается, если объект закрыт.
            ОбработкаПрерыванияПользователя();
            НоваяСтрока = ТаблицаРезультат.Добавить();
            
            // заполняем строку        
            Для каждого Колонка из ЭлементыФормы.ТаблицаРезультат.Колонки Цикл
                ОбработкаПрерыванияПользователя();
                ИмяКолонки = Колонка.Имя;
                Если ИмяКолонки = "НомерСтроки" ИЛИ ИмяКолонки = "ДатаБезВремени" Тогда
                     Продолжить;
                КонецЕсли;        
                
                Значение = RecordSet.Fields.Item(ИмяКолонки).Value;
                Если значение <> Null Тогда
                    НоваяСтрока[ИмяКолонки] = СокрЛП(Значение);
                    Если Найти(ИмяКолонки, "Id") Тогда
                        НоваяСтрока[ИмяКолонки] = СтрЗаменить(НоваяСтрока[ИмяКолонки], " ", "");
                    КонецЕсли;                                    
                КонецЕсли;            
            КонецЦикла;        
            // переходим к сл. строке        
            RecordSet.MoveNext();        
        КонецЦикла;
    Исключение
        //Предупреждение("База Скибарс занята. Повторите попытку подключения позже.");
        Сообщить(ОписаниеОшибки());
    КонецПопытки;


    ЭтаФорма.Заголовок = "Количество строк: " + ТаблицаРезультат.Количество()
        + ", времени затрачено: " + (ТекущаяДата() - ДатаНачалаДляВремени) + " секунд";
1 spock
 
21.04.17
09:24
1. Проверка на наличие временной таблицы - отдельный запрос (CommandType = 8);
2. Создание врем. таблицы - отдельный запрос (CommandType = 8);
3. Наполнение врем. таблицы и выборка из нее - отдельный запрос (CommandType = 1).

Connection = Новый COMОбъект("ADODB.Connection");
Connection.Open(СтрокаПодключения);

Command = Новый COMОбъект("ADODB.Command");
Command.ActiveConnection = Connection;
Command.CommandTimeout = 2 * 60;
Command.CommandType = 8; // 8=execution, 1=select
Command.CommandText = "SET NOCOUNT ON а далее с новой строки запрос без возврата результатов";
Command.Execute(); // а если CommandType = 1, то RecordSet = Command.Execute();
2 spock
 
21.04.17
09:27
+1 Перебор результата из recordset:

Пока RecordSet.EOF() = 0 Цикл
    НоваяСтрока = ТЗ.Добавить();
    //НоваяСтрока.<какое-то поле ТЗ> = RecordSet.Fields("ID").Value;
    
    RecordSet.MoveNext();
КонецЦикла;
3 spock
 
21.04.17
09:28
А вообще, лучше sql-код завернуть в хранимую процедуру и дергать ее из 1С с помощью Внешних источников данных.
4 Неверный Параметр И
 
21.04.17
09:37
Достаточно добавить set nocount on.
Поставщик mssql вполне позволяет выполнять батчи через ado.

И попробуй отладить запрос в managment studio, возможно он сыпеь варнингами о обработке null, тогда к set nocont on надо добавить set ansi warnings off
5 spock
 
21.04.17
09:41
(4) Запросы на проверку и создание врем. таблиц должны разноситься.
6 Неверный Параметр И
 
21.04.17
09:43
Зачем?
7 spock
 
21.04.17
09:56
(6) Возможно, это рудиментный опыт. Помниться на sql2000 были грабли, когда multi-statement запрос компилировался целиком и метаданные считывались до выполнения запроса, и не актуализировались в процессе исполнения цепочки инструкций.
8 ig0z
 
21.04.17
10:34
спасибо но достаточно было с начала запроса поставить 'SET NOCOUNT ON' и всё заработало
AdBlock убивает бесплатный контент. 1Сергей