Всем доброго дня
(платформа 1С:Предприятие 8.3 (8.3.8.2054))
(Microsoft SQL Server Standard Edition (64-bit), v. 10.0.5890.0)
Есть 2 SQL запроса, оба прекрасно отрабатывают query консоли MS SQL сервера
Но, 1й запрос так же выполняется при обращении через 1с к SQL серверу, а второй вылетает с ошибкой: Произошла исключительная ситуация (ADODB.Recordset): Operation is not allowed when the object is closed.
Работает везде:
ПолучениеСоединенияСАнкетами(Connection);
Текст =
"SELECT INV.T876c, ISNULL(INV.T990t, '') AS T990t, INV.T876p, INV.SOURCE, INV.DOC_ID, DOC.ITEM, DOC.BIBLEVEL, DOC.RECTYPE, SIGLAS.SHORTNAME, SIGLAS.ID, INV.INV_ID
|FROM SIGLAS RIGHT OUTER JOIN
| INV ON SIGLAS.ID = INV.SIGLA_ID RIGHT OUTER JOIN
| DOC ON INV.DOC_ID = DOC.DOC_ID
|WHERE (NOT (INV.T876p IS NULL))
|ORDER BY INV.DOC_ID";
RecordSet=Connection.Execute(Текст);
Показать
Работает только в консоли запросов MS SQL Server Management Studio^
ПолучениеСоединенияСАнкетами(Connection);
Текст =
"SELECT INV.T876c, ISNULL(INV.T990t, '') AS T990t, INV.T876p, INV.SOURCE, INV.DOC_ID, SUBSTRING (REPLACE (convert(varchar(1000),DOC.ITEM),CHAR(031),'!!!'),60, LEN (REPLACE (convert(varchar(1000),DOC.ITEM),' vВ наличии : инв. 2015z_',''))) as item, DOC.BIBLEVEL, DOC.RECTYPE, SIGLAS.SHORTNAME, SIGLAS.ID, INV.INV_ID
|INTO #temp1
|FROM SIGLAS RIGHT OUTER JOIN
| INV ON SIGLAS.ID = INV.SIGLA_ID RIGHT OUTER JOIN
| DOC ON INV.DOC_ID = DOC.DOC_ID
|WHERE (NOT (INV.T876p IS NULL)) AND (((SIGLAS.SHORTNAME <> 'сбо') AND (SIGLAS.SHORTNAME <> 'прокат') ) AND NOT INV.T876p like('%P%'));
|
|SELECT T876p, REPLACE (ITEM, CHAR(030),'###') as ITEM, INV_ID, T990t
|INTO #temp2
|FROM #temp1;
|
|SELECT replace (ITEM,'###100__!!!a','###100') AS ITEM, T876p, INV_ID, T990t
|FROM #temp2
|
|ORDER BY ITEM
|
|DR OP TABLE #temp1
|DR OP TABLE #temp2";
RecordSet=Connection.Execute(Текст);
Показать
Вот сама строка соединения:
&НаСервереБезКонтекста
Функция ПолучениеСоединенияСАнкетами(Connection) Экспорт
Connection = Новый COMОбъект("ADODB.Connection");
Connection.Open ("DRIVER={SQL Server};SERVER=XXX;UID=Login;PWD=PASSWORD;DATABASE=baseName");
КонецФункции
При всем при этом "Execute" выполняет запрос, т.к. выполнение не прерывается, пока не поптаешься перебрать выборку "RecordSet.EOF"
(3) donyab, у меня ваших таблиц нет, потому просто редактирование текста запроса.
SEL ECT replace (ITEM,'###100__!!!a','###100') AS ITEM, T876p, INV_ID, T990t
FR OM --#temp2
(
SEL ECT T876p, REPLACE (ITEM, CHAR(030),'###') as ITEM, INV_ID, T990t
FR OM -- #temp1;
(
SELECT INV.T876c, ISNULL(INV.T990t, '') AS T990t, INV.T876p, INV.SOURCE, INV.DOC_ID, SUBSTRING (REPLACE (convert(varchar(1000),DOC.ITEM),CHAR(031),'!!!'),60, LEN (REPLACE (convert(varchar(1000),DOC.ITEM),' vВ наличии : инв. 2015z_',''))) as item, DOC.BIBLEVEL, DOC.RECTYPE, SIGLAS.SHORTNAME, SIGLAS.ID, INV.INV_ID
FR OM SIGLAS RIGHT OUTER JOIN
INV ON SIGLAS.ID = INV.SIGLA_ID RIGHT OUTER JOIN
DOC ON INV.DOC_ID = DOC.DOC_ID
WH ERE (NOT (INV.T876p IS NULL)) AND (((SIGLAS.SHORTNAME <> 'сбо') AND (SIGLAS.SHORTNAME <> 'прокат') ) AND NOT INV.T876p like('%P%'))
) t1
) t2
ORDER BY ITEM
(10) donyab, ну, можно и так... Хотя лучше просто убрать удаление временных таблиц. Они с убиением коннекта сами умрут. И ваш первоначальный вариант не работал именно из-за этого дропания.
(11) sssss_aaaaa_2011,
Нет, проверял первым делом.
Не дропал, ошибка была таже самая.
И с убиением не умирают. Проверял через SQL, они хранятся в tempd и при 2 запуске запроса SQL ругается, что такая временная таблица уже создана.
Я полагаю, что после перезагрузки скуля удалятся.
Ну, после перезагрузки уж всяко удалятся ибо при этом сама tempdb пересоздастся. А вот с вашими выводами и проверками не соглашусь, что-то где-то не так вы делали.
1. Временные таблицы живут до закрытия соединения, если их не дропать. Они им изолированы. В этом их смысл. Самое смешное, что одинэсный объект с пафосным названием МенеджерВременныхТаблиц на самом деле тупая ссылка на соединение (чтобы разные запросы выполнялись в одном соединении с одними и теми же временными таблицами). Ну не совсем тупая. Она как бы управляет временем жизни соединения на самом деле.
2. Не пробовал, но ADODB вроде как поддерживает обработку множественных результатов пакетного запроса.
https://msdn.microsoft.com/en-us/library/ms677539(v=vs.85).aspx
Столкнулся с такой же проблемой и ошибкой, когда хотел использовать процедуры которая на MS SQL Server Management Studio отрабатывает корректно а в 1С выдавала ошибку: Operation is not allowed when the object is closed
А сама проблема была в процедуре. По умолчанию параметр SET NOCOUNT имеет статус OFF, соответственно решение надо дописать в процедуру SET NOCOUNT ON и все тогда работает.
решение нашел здесь:
что то не понятно как то, может кто подскажет, та же беда :( не ясно что закрывает объект.
В студии все работает на ура
Соединение = Новый COMОбъект("ADODB.Connection");
Соединение.ConnectionString = СтрокаСоединения;
Соединение.Open();
Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = Соединение;
Команда.CommandText = ТекстЗапроса;
Выборка = Новый COMОбъект("ADODB.RecordSet");
Выборка = Команда.Execute();
Если Выборка.EOF() Тогда //тут падает Operation is not allowed when the object is closed.
Показать
Сам запрос вот такой:
ТекстЗапроса = "
|SET NOCOUNT ON
|-- Список проблемных заданий
|USE MSDB
|;WITH CTE_MostRecentJobRun AS
|(
|-- For each job get the most recent run (this will be the one where Rnk=1)
|SELECT job_id,run_status,run_date,run_time
|,RANK() OVER (PARTITION BY job_id ORDER BY run_date DESC,run_time DESC) AS Rnk
|FROM sysjobhistory
|WHERE step_id=0
|)
|SELECT
|name AS [JobName],
|CONVERT(VARCHAR,DATEADD(S,(run_time/10000)*60*60 /* hours */
| +((run_time - (run_time/10000) * 10000)/100) * 60 /* mins */
| + (run_time - (run_time/100) * 100) /* secs */,
| CONVERT(DATETIME,RTRIM(run_date),113)),100) AS [TimeRun],
|CASE WHEN enabled=1 THEN 'Enabled'
| ELSE 'Disabled'
| END AS [JobStatus]
|FROM CTE_MostRecentJobRun MRJR
| JOIN sysjobs SJ ON MRJR.job_id=sj.job_id
|WHERE Rnk = 1
| AND run_status = 0 -- i.e. failed
|ORDER BY name
|";
Для тех, кто столкнется с этой проблемой: я решил проблему следующим образом: переделал временные таблицы на CTE.
Пример:
SEL ECT
PriceBuffer._PIN AS PIN,
PriceBuffer._Brand AS Brand,
PriceBuffer._PartnerID AS PartnerID,
PriceBuffer._PriceCurrency AS PriceCurrency
INTO #tblPriceBuffer
FROM trade_add_t.dbo.PriceBuffer
;
SEL ECT
PriceBuffer.PIN AS PIN,
PriceBuffer.Brand AS Brand,
PriceBuffer.PartnerID AS PartnerID,
PriceBuffer.PriceCurrency AS PriceCurrency
FROM #tblPriceBuffer AS PriceBuffer
;
DR OP TABLE #tblPriceBuffer
Показать
WITH CTE_PriceBuffer AS
(
SELECT
PriceBuffer._PIN AS PIN,
PriceBuffer._Brand AS Brand,
PriceBuffer._PartnerID AS PartnerID,
PriceBuffer._PriceCurrency AS PriceCurrency
FR OM trade_add_t.dbo.PriceBuffer
)
SELECT
PriceBuffer.PIN AS PIN,
PriceBuffer.Brand AS Brand,
PriceBuffer.PartnerID AS PartnerID,
PriceBuffer.PriceCurrency AS PriceCurrency
FR OM CTE_PriceBuffer AS PriceBuffer