Имя: Пароль:
1C
 
ADODB.Connection
0 DenIv
 
25.11.08
10:24
Добрый день
не поможете разобраться

Пишу в 1С, через ADODB
А задача очень простая:
Если это DELETE FROM ... или INSERT, то нужно знать AffectedRecords
у меня почему-то не работает
Казалось бы, в документации описано:
Execute(CommandText, RecordsAffected, Options)

Выполняет запрос, оператор SQL, хранимую процедуру или любую другую команду, доступную провайдеру. Возвращает объект Recordset, доступный только для чтения курсором Forward-only, если переданная команда возвращает записи. (Если нужен объект Recordset, доступный для записи, следует создать его непосредственно, и воспользоваться его свойствами и методами.) Параметры:
CommandText - обязательный. Строка, содержащая оператор SQL, имя таблицы, хранимой процедуры или другую команду провайдера.
RecordsAffected - необязательный. Целое число (long), определяющее число записей, затронутых командой. Заполняется провайдером.

Делаем что-то типа
Соединение = СоздатьОбъект("ADODB.Connection");
// строка соединения
ConnectionString = СокрЛП(Константа.NX_MySQL_Driver)+
"; server=" +СокрЛП(Константа.NX_MySQL_Server)+
"; uid=" +СокрЛП(Константа.NX_MySQL_User)+
"; pwd=" +СокрЛП(Константа.NX_MySQL_Password)+
"; database=" +СокрЛП(Константа.NX_MySQL_DataBase)+";";
Соединение.Open(ConnectionString);
Affected = 0;
Соединение.Execute(Запрос,Affected);

И, тепля в душе надежду увидеть в переменной Affected воджеленный AffectedRecords, запускаем, и ... болт, короче. "0".

Заранее признателен
1 ТелепатБот
 
гуру
25.11.08
10:24
2 ДенисЧ
 
25.11.08
10:25
Скорее всего, не сработает.
Пиши перед операторами - селект count(*) с теми же условиями.
3 DenIv
 
25.11.08
10:27
(2) криво, если 100 инсертов в приличного размера таблицу? каждый раз делать select count(*) FROm таблица? неужели нет другого способа? и почему "скорее всего не сработает"?
4 ДенисЧ
 
25.11.08
10:29
(3) это микрософт :-)
Попробуй поиграться типами курсоров. Да и от драйвера ODBC много зависит.
5 DenIv
 
25.11.08
10:35
(4) можно поподробнее
6 DenIv
 
25.11.08
10:40
ап
7 Попытка1С
 
25.11.08
10:46
Вот я гружу из аксапты документы:
В текстовом файле все параметры одной строкой:
driver={SQL Server};server=spbaxdb02;uid=axapta;pwd=axaLogin;Database=LVNProd_Work

Функция ИнициализацияАДО()
   Соединение=СоздатьОбъект("ADODB.Connection");
   ФайлСтрокиКонн = КаталогИБ() + "\ADOString\Axapta_WORK.txt";
   Конфиг=СоздатьОбъект("Текст");
   Конфиг.Открыть(ФайлСтрокиКонн);
   СтрокаКоннекта=СокрЛП(Конфиг.ПолучитьСтроку(1));
   Соединение.ConnectionTimeOut=20;
   Соединение.CursorLocation=3;
   Попытка
       Соединение.Open(СтрокаКоннекта);
   Исключение
       Возврат 0;
   КонецПопытки;
   Возврат 1;
КонецФункции

инсерт делаю так например:
ЗапросАДО=СоздатьОбъект("ADODB.RecordSet");
       ЗапросАДО.ActiveConnection=СоединениеБлок;
       ЗапросАДО.CursorType = 1;
       ЗапросАДО.LockType = 3;
Пока СписокДоковВОбъеденении.ПолучитьСтроку() = 1 Цикл
           ТЗ="insert DOC_LOCK (doc_num, doc_type, doc_date, doc_num_new) " +
           "VALUES ('"+СокрЛП(СписокДоковВОбъеденении.НомерДокумента)+"','"
           +СписокДоковВОбъеденении.ТипДокумента+"','"
           +Дата(СписокДоковВОбъеденении.ДатаДокумента)+"','"
           +СокрЛП(СписокДоковВОбъеденении.НомерНовогоДока)+"')" ;
           ЗапросАДО.Open(ТЗ);
       КонецЦикла;
Все работает.
8 DenIv
 
25.11.08
11:22
(7) а де в этом примере получение кол-ва записей затронутых INSERT-ом?
9 DenIv
 
25.11.08
11:26
апп
10 Sadovnikov
 
25.11.08
11:33
(0) А в MySQL нету, как в MS SQL, переменной @@RowCount?
11 774816
 
25.11.08
11:41
(10)при таков вводе в скул
insert into test (name) values('ss')
insert into test (name) values('112')
select @@ROWCOUNT
возвращает 1 хотя введено 2 значение
но когда работаем через select выдает правильно
insert into test (name)
select name from test
select @@ROWCOUNT
12 Sadovnikov
 
25.11.08
11:42
(11) Дык об этом прямо в документации и написано - @@RowCount выдает количество строк, подпавших под ПОСЛЕДНЕЕ действие.
13 DenIv
 
25.11.08
11:53
Соединение = СоздатьОбъект("ADODB.Connection");
РекордСет = СоздатьОбъект("ADODB.RecordSet");

// строка соединения

ConnectionString = "....";
Соединение.Open(ConnectionString);
Запрос= "
|BEGIN
|DECLARE @TableName varchar(32)
|DECLARE @DBSIGN char(3)
|SELECT @DBSIGN='СРГ'
|SELECT @DBSIGN='SC14645'
|begin transaction
|INSERT INTO _1sUPDTS (DBSIGN,TYPEID,OBJID,DELETED,DWNLDID)
|            select
|            right(id,3) as DBSIGN,
|            Cast (Right('+@TableName+',LEN('+@TableName+')-2) AS int) TYPEID,
|            id as OBJID,
|            '' as DELETED,
|            '' as DWNLDID
|           from @TableName
|           WHERE right(id,3)='+@DBSIGN+' AND id NOT IN(SELECT OBJID FROM _1SUPDTS)
|commit transaction
|SELECT @@ROWCOUNT AS Affected
|END
";
Affected = 0;
РекордСет =Соединение.Execute(Запрос,Affected);

РекордСет - пустой, Affected = 0 :(
14 Sadovnikov
 
25.11.08
11:55
(13) Я так и не понял - это какой скуль? Если MS SQL, то:
1. убери транзакцию.
2. убери Begin End
3. в начало запроса вкатай Set NoCount On
15 DenIv
 
25.11.08
11:56
при этом записи в _1SUPDTS добавляются
16 774816
 
25.11.08
11:57
SET @DBSIGN='СРГ'
SET @DBSIGN='SC14645'

РекордСет =Соединение.Execute(Запрос);
Сообщить(РекордСет.Fields("Affected").Value)
17 Sadovnikov
 
25.11.08
11:58
+(14) Похоже, все-таки MS SQL. Да еще и 1С. Тогда нафига тебе ADODB? Возьми 1С++ и не мучайся.
18 DenIv
 
25.11.08
11:59
(14)
Begin End и transaction - добавлял в качестве экспиримента для того чтобы набор оперераторов выполнялся одним блоком, так что 1.2. результатов не дает :( не понимаю каким образом поможет Set NoCount On?
19 DenIv
 
25.11.08
11:59
(17) использование ВК запрещено
20 Sadovnikov
 
25.11.08
12:00
(18) "не понимаю каким образом поможет Set NoCount On?" - тем, что сможешь получить свой вожделенный результат второго запроса. Который
SELECT @@ROWCOUNT AS Affected
21 Sadovnikov
 
25.11.08
12:01
(19) Чего??? Напрямую писать в таблицы, используя внешние средства, значит, вам не запрещено. А использовать ВК - запрещено???
Это кто ж такой бред-то придумывает??
22 Sadovnikov
 
25.11.08
12:04
Вот это:
Cast (Right('+@TableName+',LEN('+@TableName+')-2) AS int) TYPEID
радует аж неимоверно... Кто автор сего творения?
23 DenIv
 
25.11.08
12:20
(20) респект и уважуха!!! сработало, если не сложно поясни, а то я в первоначальном варианте использовал наоборот Set NoCount OFF, думая что данная комманда как раз отключает сообщения СКЛ и как раз нивно полагал что все делаю правильно. так как же работает/на что влияет  Set NoCount?
24 DenIv
 
25.11.08
12:22
(22) а что собственно смущает в
Cast (Right(@TableName,LEN(@TableName)-2) AS int) TYPEID ?
25 DenIv
 
25.11.08
12:23
на перезапись ср-вами 1С уходт порядка 30 часов, отсюда и решил пререзаписать T-SQL
26 Sadovnikov
 
25.11.08
12:25
(23) Set NoCount On отключает вывод служебных сообщений. У тебя драйвер словил это самое сообщение и дальше смотреть результат запроса не стал. Следовательно, ты потерял необходимую тебе информацию.
(24) Зачем заставлять скуль статику рассчитывать? На этапе формирования запроса этого сделать разве нельзя? Да и запрос более читабельным получится.
(25) "отсюда и решил пререзаписать T-SQL" - правильно решил. Вот, только еще и инструмент для этого правильный возьми.
Как, кстати, получаешь SC14645?
27 DenIv
 
25.11.08
12:30
Как, кстати, получаешь SC14645
для перезаписи справочников можно написать курсор, перебирающий все пользователевские таблицы по выбранной БД, начинающиеся с SC (в данном случае без transaction не удалось обойтись), если выборочно, то парсим DDS и получаем имена таблиц с привязкой к объекту метаданных.

DECLARE @TableName varchar(32)

DECLARE @DBSIGN char(3)

DECLARE @SQL varchar(8000)

DECLARE SysCur CURSOR FOR select name From sysobjects where left(name,2)='SC'

SELECT @DBSIGN='СРГ'

OPEN SysCur

FETCH NEXT FROM SysCur INTO @TableName

 WHILE @@FETCH_STATUS=0 BEGIN

     SELECT @SQL='

     INSERT INTO _1sUPDTS (DBSIGN,TYPEID,OBJID,DELETED,DWNLDID)

           select

           right(id,3) as DBSIGN,

           Cast (Right('''+@TableName+''',LEN('''+@TableName+''')-2) AS int) TYPEID,

           id as OBJID,

                       '''' as DELETED,

                       '''' as DWNLDID

     from

           '+@TableName+'

     WHERE

           right(id,3)='''+@DBSIGN+''' AND id NOT IN(SELECT OBJID FROM _1sUPDTS)'

           begin transaction

           exec(@SQL)

           commit transaction

     FETCH NEXT FROM SysCur INTO @TableName

 END

CLOSE SysCur

DEALLOCATE SysCur



Документы все слава богу в одной таблице


INSERT INTO _1sUPDTS (DBSIGN,TYPEID,OBJID,DELETED,DWNLDID)

SELECT

     right(iddoc,3) as DBSIGN,

     iddocdef as TYPEID,

     iddoc as OBJID,

           '' as DELETED,

           '' as DWNLDID

FROM _1SJOURN

WHERE right(iddoc,3)= @DBSIGN

AND iddoc NOT IN(SELECT OBJID FROM _1sUPDTS)
28 Sadovnikov
 
25.11.08
12:31
(27) Опупеть... Это вы так базу ускоряеете??
Еще раз повторюсь - возьмите 1С++ !!!
Или, хотя бы, посмотрите, что возвращает метод ЗначениеВСтрокуВнутр()...
29 DenIv
 
25.11.08
12:33
(27) Опупеть... Это вы так базу ускоряеете??
поясни, что конкретно не правильно
30 Sadovnikov
 
25.11.08
12:34
(29) Весь подход к работе неправильный. Вы пытаетесь изобрести велосипед с квадратными колесами.
31 Sadovnikov
 
25.11.08
12:35
+(30) "то парсим DDS и получаем имена таблиц с привязкой к объекту метаданных" - зачем так-то над базой издеваться???
32 DenIv
 
25.11.08
12:39
(30) голословно, аргументируй
33 DenIv
 
25.11.08
12:39
(28) Еще раз повторюсь - использовать ВК запрещено!
34 Sadovnikov
 
25.11.08
12:40
+(30) "в данном случае без transaction не удалось обойтись" - почему??
35 rs_trade
 
25.11.08
12:41
(33) уж лучше ВК чем так...
36 Sadovnikov
 
25.11.08
12:41
(32) См. (31).
(33) Да что ж за дятел-то придумал такое ограничение? Ради чего оно? ADODB - не ВК, по болшому счету??
37 DenIv
 
25.11.08
12:53
(34) записис в _1sUPDTS не попадают
38 Sadovnikov
 
25.11.08
13:00
(37) Чего?? Это... Может, вам стоит специалиста вызвать?...
39 DenIv
 
25.11.08
14:00
крут слов нет... попробуй сам ... убедишься опытным путем
40 Sadovnikov
 
25.11.08
14:03
(39) А ты таки думаешь, что я запросы никогда не писал и не знаю, как Insert работает?
41 Sadovnikov
 
25.11.08
14:08
(39) Любуйся:

Declare @ТекстЗапроса varChar(3000)

Create Table Тест(Колонка1 int)

Set @ТекстЗапроса = 'Insert Into Тест Values(1)'
Exec(@ТекстЗапроса)

Select *
From Тест

Drop Table Тест

И думай, что нужно в консерватории менять.
42 DenIv
 
25.11.08
14:26
при использовании курсора не прокатывает
43 Sadovnikov
 
25.11.08
14:32
(42) Обманывать-то зачем???
Declare @ТекстЗапроса varChar(3000)

Create Table #T(K Int)
Insert Into #T Values(1)
Insert Into #T Values(2)
Insert Into #T Values(3)

Create Table Тест(Колонка1 int)

DECLARE Курсор CURSOR FOR
   Select K From #T

Declare @K Int

OPEN Курсор

FETCH NEXT FROM Курсор INTO @K
WHILE @@FETCH_STATUS=0 BEGIN
   Set @ТекстЗапроса = 'Insert Into Тест Values('+Cast(@K As Char(1))+')'
   Exec(@ТекстЗапроса)

   FETCH NEXT FROM Курсор INTO @K
END

CLOSE Курсор
DEALLOCATE Курсор

Select *
From Тест


Drop Table Тест
Drop Table #T

Курите мануалы...
44 Sadovnikov
 
25.11.08
14:51
(42) Куда пропал? Такой интересный бред писал...
Я требую продолжения банкета! :)
45 DenIv
 
26.11.08
08:52
сформулируй что именно в твоем понимании бред? Перезапись объектов не средствами 1С? отказ от использования ВК? или что-то еще?
46 DenIv
 
26.11.08
09:09
в (43) - пытаешься доказать что не нужно использовать begin - commit transaction? чем принципиально код отличается от моего?
47 Sadovnikov
 
26.11.08
09:24
(54) Твои высказывания бред... Точнее, незнание T-SQL. Пример такого в (42).
48 Sadovnikov
 
26.11.08
09:25
(46) Я не пытаюсь, а показываю, что ты абсолютную фигню писал. Причем, безапелляционно. И мягко намекаю, что стоит BOL почитать...
49 DenIv
 
26.11.08
09:30
с (42) соглашусь, проблема вызвана не использованием курсора. ни в одном из моих постов я не писал, что я гуру в T_SQL. вывод об "абсолютной фигне" ты делаешь только на основании (42)?
50 Sadovnikov
 
26.11.08
09:31
(49) Нет, не только на основании (42). Просто еще раз веточку внимательно прочитай.
51 Sadovnikov
 
26.11.08
09:32
Я прекрасно понимаю, что все мы начинающие. НО ведь начинать-то можно по разному. Например, прислушаться к советам того, кто в обсуждаемом разделе знает чуть больше.
52 DrZombi
 
гуру
26.11.08
09:33
(0)(33)Это кем тебе запрещено :)
Ведать начальникО у тебя садист :)
53 Sadovnikov
 
26.11.08
09:37
(52) А меня поражает странная однокость этого запрета. Значит, можно писать (!!!) в базу сторонними средствами (по большому счету - ВК). А вот нормальным инструментом для этого пользоваться нельзя.
Как-то странно это, не так ли?
54 DenIv
 
26.11.08
09:39
а так запросто без загадок сформулировать западло что ли?
55 Sadovnikov
 
26.11.08
09:41
(54) Это ты о чем сейчас?
56 DenIv
 
26.11.08
09:45
т.е. я делаю вывод - что камень предкновения отказ от использования 1с++? Вывод - раз так то все что написано бред? АДО врядли можно назвать ВК, компонента в составе винды, ее по определению не может не быть на виндовых РС. Целесобразность использования обоснуйте, лично я не вижу смысла. Раз у Вас болше опыта, распишите плюсы зачем мне ВК если все можно реализовать без нее.
57 DenIv
 
26.11.08
09:47
(55) ты неоднократно пишешь, что все что предложено мной бред. У меня возникает (так же неоднократно) вопрос почему? обоснуйте. В ответ я слышу только что-то типа - "Просто еще раз веточку внимательно прочитай". вот я и прошу конкретизировать. Понятно объяснил?
58 Sadovnikov
 
26.11.08
09:47
(56) "т.е. я делаю вывод - что камень предкновения отказ от использования 1с++? " - Я вот не могу понять - ты читаешь только то, что тебе удобно?
" зачем мне ВК если все можно реализовать без нее" - можно и без АДО реализовать. Только штатными методами. Но, ведь, была же причина от них откзаться? Так же и с ВК.
59 DenIv
 
26.11.08
09:49
(58) можно и без АДО реализовать
можно, но перезапись идет более 30-ти часов, T-SQL - 7 мин.

Так же и с ВК

зачем, если все реализуется без ВК, я с даной ВК не работал в (56) просил, объяснить в чем курутость
60 Sadovnikov
 
26.11.08
09:53
(57) Бред:
1. Отказ от использования ВК. Результат: потеря скорости программирования, снижение скорости работы базы, потеря очень больших вкусностей как для программиста, так и для пользователя. Ты в курсе, что просто загрузка ВК 1С++ уже ускоряет работу базы? Как минимум, за счет нормального поиска процедур и функций в том же глобальном модуле и нормальной (не тормозной) работы метода СоздатьОбъект()?
2. Использование в селекте конструкции
Cast (Right('+@TableName+',LEN('+@TableName+')-2) AS int) TYPEID
3. Использование транзакции для единственного инсерта.
4. Парсинг DDS для получения имен таблиц. Даже штатными средствами 1С это можно сделать гораздо быстрее, без этого парсинга. Плюс далеко не все поля прописаны в DDS.
5. Фраза "при использовании курсора не прокатывает <инсерт без транзакции>"
Хватит? Обосновал я?
61 Sadovnikov
 
26.11.08
09:55
(59) Крутость 1С++:
1. п. 1 из (60)
2. Метапарсер для T-SQL
3. Полноценный ООП
4. Шикарные встроенные классы: ИндексированнаяТаблица, ТабличноеПоле, Перехватчик, Информатор и т.д.
5. Возможность использования активиксов на формах 1С.
6. очень многое другое. Подробнее посмотри на www.1cpp.ru
62 DenIv
 
26.11.08
10:04
(60)
1. ничего не могу сказать так как не использовал данную ВК
2. каким образом только средствами T-SQL можно получить ID таблицы справочника кроме предложенного Cast (Right(@TableName,LEN(@TableName)-2) AS int) AS TYPEID? лично я не вкурсе, если есть другой способ расскажи буду признателен.
3. см. (49), хотя ты никак не обосновал почему это зло, а avto commit нет.
4. как без использования ВК получить ID объектов штатными средствами 1С,расскажи буду признателен.
5. =3, давай уже закроем, я предполагал, что поскольку многократные инсерты в курсоре нужно коммитить, т.к. возможно после закрытия курсора без коммита данные не поподают в таблицу инсерта. Уже признал, что был не прав, но повторюсь, ты никак не обосновал почему это зло, а avto commit нет.
63 Sadovnikov
 
26.11.08
10:09
(62)
2. Способ правильный. Только зачем это делать в селект-листе?
3. Почему сразы зло? Просто, бессмысленно это. Зачем?
4. Выковырять его из строки, которую возвращает метод ЗначениеВСтрокуВнутр().
64 DenIv
 
26.11.08
10:16
2. Тоже согласен более оптимально.
4. Не догнал, каюсь.
Спасибо
не согласен с выводом относительно бреда, не рационально - да.
65 Sadovnikov
 
26.11.08
10:23
(64)
4. ЗначениеВСтрокуВнутр(СоздатьОбъект("Справочник.Номенклатура")) = {"B","0","0","12","0","0","         0   "}
12 - ИД справочника Номенклатура. ТОесть, таблица бедет называться SC12.
66 DenIv
 
26.11.08
10:46
(65) я в курсе, но почему-то забыл про этот метод