powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / [игнор отключен] [закрыт для гостей] / Непонятное поведение ADODB в 1С 8.0
6 сообщений из 6, страница 1 из 1
Непонятное поведение ADODB в 1С 8.0
    #34937078
_roadster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Непонятное поведение ADODB в 1С 8.0
Есть необходимость записи данных в произвольную базу на MS SQL 2005 Standard.
Запись реализуется с помощью хранимых процедур.

Пример хранимой процедуры:
CREATE PROCEDURE TestProc
@ID Int OUTPUT,
@F1 NChar(10)
AS
BEGIN
INSERT INTO TestTable (F1)
VALUES (@F1)
SET @ID = SCOPE_IDENTITY()
END
GO

То есть, эта процедура добавляет запись в таблицу, пишет переданное значение в поле F1 и позвращает значение Identity параметром @ID.
Процедура рабочая. Работает и в QueryAnalyser, и в Delphi (TADOCommand). Identity возвращается нормально.

Теперь код в 1С 8.0

Процедура ТестСКЛ()
Перем пСтрСоед;
Перем пСоед;
Перем пКом;
Перем пРС;
Перем пИД;

пСтрСоед = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DocExchange1C;Data Source=SRV01";
пСоед = Новый COMОбъект("ADODB.Connection");
пСоед.Provider = "SQLOLEDB";
пСоед.ConnectionTimeout = 15;
пСоед.CommandTimeOut= 30;
пСоед.ConnectionString = пСтрСоед;
пСоед.Open();

пКом = Новый COMОбъект("ADODB.Command");
пКом.ActiveConnection = пСоед;
пКом.CommandType = 4;
пКом.CommandText = "TestProc";
пКом.Parameters("@F1").Value = "qqq";
пРС = пКом.Execute();
пИД = пКом.Parameters("@ID").Value;
Предупреждение(пИД);
пСоед.Close();
КонецПроцедуры

Код отрабатывает без ошибок, запись в базу добавляется, но выходной параметр процедуры @ID равен Null (видно по отладчику).
Опыты показали, что выходной параметр все- таки возвращается в 1С, если в тексте нет конструкций INSERT, UPDATE или DELETE, или если он присваивается до них.
То есть, если

CREATE PROCEDURE TestProc
@ID Int OUTPUT,
@F1 NChar(10)
AS
BEGIN
SET @ID = 111
END
GO

Или

CREATE PROCEDURE TestProc
@ID Int OUTPUT,
@F1 NChar(10)
AS
BEGIN
SET @ID = 111
INSERT INTO TestTable (F1)
VALUES (@F1)
END
GO

Тогда выходной параметр @ID будет возвращен в 1С со значением 111.

Создается такое впечатление, что ADODB.Connection, будучи использован в 1С, игнорирует выходные параметры процедуры, если их присвоение производится после INSERT (UPDATE,DELETE)
Кстати, если в процедуре после INSERT (UPDATE, DELETE) производится SELECT, то рекордсет в таких случаях всегда возвращается в 1С пустой.

Вопрос: Как побороть такую глюку?
...
Рейтинг: 0 / 0
Непонятное поведение ADODB в 1С 8.0
    #34938185
ZrenBy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_roadsterВопрос: Как побороть такую глюку?

Код: plaintext
1.
set nocount on
...
Рейтинг: 0 / 0
Непонятное поведение ADODB в 1С 8.0
    #34944641
_roadster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Уже догадался :0)

CREATE PROCEDURE TestProc
@ID Int OUTPUT,
@F1 NChar(10)
AS
BEGIN
INSERT INTO TestTable (F1)
VALUES (@F1)
SET NOCOUNT ON
SET @ID = SCOPE_IDENTITY()
END
GO

Так параметры нормально возвращаются.
Важно ставить этот SET до возврата параметра, но после инсерта, иначе, как показывает эксперимент, RecordsAffected неверный будет

Или так
CREATE PROCEDURE TestProc
@ID Int OUTPUT,
@RecordsAffected Int OUTPUT,
@F1 NChar(10)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO TestTable (F1)
VALUES (@F1)
SET @ID = SCOPE_IDENTITY()
SET @RecordsAffected = @@ROWCOUNT
END
GO
...
Рейтинг: 0 / 0
Непонятное поведение ADODB в 1С 8.0
    #34944669
_roadster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще вопрос.
Дельфийный TADOCommand, без указания SEN NOCOUNT ON, тем не менее, нормально интерпретирует выходные параметры.
Как бы ADODB.Command в 1С также подкрутить?
Смотрел исходники TADOCommand, ничего такого не нашел...
...
Рейтинг: 0 / 0
Непонятное поведение ADODB в 1С 8.0
    #34944962
ZrenBy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_roadsterЕще вопрос.
Дельфийный TADOCommand, без указания SEN NOCOUNT ON, тем не менее, нормально интерпретирует выходные параметры.
Как бы ADODB.Command в 1С также подкрутить?
Смотрел исходники TADOCommand, ничего такого не нашел...

Использовать
Код: plaintext
NextRecordset

В твоем случае будет так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	пРС = пКом.Execute();
	Пока Истина Цикл
		Если пРС.State <>  0  Тогда //adStateClosed
			Прервать;
		КонецЕсли;
		пРС = пРС.NextRecordset();
		Если пРС = Неопределено Тогда
			Прервать;
		КонецЕсли;
	КонецЦикла;
	пИД = пКом.Parameters("@ID").Value;
...
Рейтинг: 0 / 0
Непонятное поведение ADODB в 1С 8.0
    #34946900
Фотография PA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RTFM:
"When ADO is returning "output" or "return" parameter values to the user from a datasource, ADO will only read the values once from the provider. This means that if the user reads the values before they are ready, they may not be retrieved.
Accessing the parameter value before the recordset has been closed on a forward-only, read-only cursor on Microsoft SQL Server will result in the parameter value being retrieved before it's available. Referring to the parameter only after the recordset was closed (instead of before and after) will retrieve the correct parameter value."

Так что использование NextRecordset здесь просто удачное совпадение (из-за уничтожения ссылки на текущий рекордсет).
Достаточно вообще не получать ссылку на рекордсет:
Код: plaintext
1.
2.
пКом.Execute();
пИД = пКом.Parameters("@ID").Value;
Предупреждение(пИД);
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / [игнор отключен] [закрыт для гостей] / Непонятное поведение ADODB в 1С 8.0
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]