Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 7.7 и ранее

v7: Примитивный запрос UPDATE :-)

v7: Примитивный запрос UPDATE :-)
Я
   MWWRuza
 
09.10.20 - 22:04
Добрый вечер!
В продолжение(точнее, "по мотивам") темы: Замена ссылок в движениях регистров(в таблицах DBF)
Там я реальную проблему решил, конвертнул базу в SQL, воспользовался обработкой, поменял что нужно, и сконвертил в DBF обратно. Все получилось, нет проблем.
Но, захотелось все-таки что-то такое под DBF сделать, что-бы при необходимости обходиться без этих "плясок с бубном" с конвертацией туда-обратно.

В посте (7) Ёпрст писал: "Написать примитивный запрос на update нужных табличек проще всего на vfpoledb, синтаксис не особо и отличаться будет от запроса для mssql"...
Пошел по этому пути. Но опыта в прямых запросах - явно не хватает :-(
Первая часть, по поиску ссылок, заработала без особых проблем.
А вот вторая, по замене - ну никак не хочет работать...
Вот так это выглядит в отладчике: https://content.foto.my.mail.ru/mail/m_w_w/_mypagephoto/h-351.jpg
На следующем шаге падает с ошибкой, вот так: https://content.foto.my.mail.ru/mail/m_w_w/_mypagephoto/h-352.jpg
Текст ошибки:
рс.ВыполнитьИнструкцию(ТекстЗапроса);
{D:\BASA_1C\ВЕГА\ЗАМЕНАЭЛЕМЕНТАДБФ.ERT(689)}: FAILED! ICommandText::Execute(): Record is not locked.

Вот текст самого запроса:
                База = СоздатьОбъект("OLEDBData");
                Соединение = "Provider=VFPOLEDB.1;Data Source=" + КаталогИБ()+ ";Mode=ReadWrite;Collating Sequence=MACHINE";
                Если База.Соединение(Соединение) = 0 Тогда
                    Сообщить("Не соеденились");
                    Возврат;
                КонецЕсли;
                рс = База.СоздатьКоманду();                
                
                ТекстЗапроса = "
                |UPDATE  
                |    $"+тзПотомки.Метаданные+"
                | SET $"+тзПотомки.Метаданные+"."+тзПотомки.Реквизит +" = :Объект
                |FROM $"+тзПотомки.Метаданные+" AS Tab
                |where (Tab.IDDOC = :Док)
                | AND  ($Tab."+тзПотомки.Реквизит+" = :Источник)
                |";
                рс.УстановитьТекстовыйПараметр("Объект", Приемник);
                рс.УстановитьТекстовыйПараметр("Источник", Источник);
                рс.УстановитьТекстовыйПараметр("Док", Док.ТекущийДокумент());
        //        рс.Выполнить("EXECSCRIPT('SET ANSI OFF')");
                рс.ВыполнитьИнструкцию(ТекстЗапроса);

Все-таки, видимо синтаксис не особо, но отличается... Такое ощущение, что он не может получить доступ к таблице на запись...
Подскажите пожалуйста, что я не правильно делаю?
   МихаилМ
 
1 - 09.10.20 - 22:56
   Ёпрст
 
2 - 09.10.20 - 23:35
(0)

    ОлеДБ = СоздатьОбъект("OLEDBData");
    Соединение = "Provider=VFPOLEDB.1;Data Source=" + КаталогИБ() + ";Mode=ReadWrite;Collating Sequence=MACHINE";
    Рез = ОлеДБ.Соединение(Соединение);
    Запрос = ОлеДБ.СоздатьКоманду();
    Запрос.Выполнить("EXECSCRIPT('SET ANSI OFF')");  
    Запрос.Выполнить("EXECSCRIPT('SET REPROCESS TO 60 SECONDS')");
    Запрос.Выполнить("EXECSCRIPT('SET REFRESH TO 0,-1')");    
    Запрос.Выполнить("Exec('SET TABLEVALIDATE TO 0')");
    Запрос = ОлеДБ.СоздатьКоманду();
    ТекстЗапроса = "
    |Update
    |   Вася
    |Set
    |   $Вася.Реквизит=:Параметр
    |
    |from $Справочник.Вася as Вася
    |
    |";
    Запрос.УстановитьТекстовыйПараметр("Параметр", "Лошпед");
    Запрос.ВыполнитьИнструкцию(ТекстЗапроса);


ЗЫ: пихать метаданные...да уж.
Если че, есть Идентификатор у метаданных.
   Ёпрст
 
3 - 09.10.20 - 23:36
и.. Запрос.Отладка(1) надо показывать на форуме, если че..
   МихаилМ
 
4 - 09.10.20 - 23:41
(3) а как быть с длинными строками и не ограниченной длинны. рни вроде хранятся отдельно по 500 байт
   Ёпрст
 
5 - 09.10.20 - 23:44
(4) да, в блобе хранятся блоками, там тупо искать все блоки и апдейтить ..кусками
   Ёпрст
 
6 - 09.10.20 - 23:48
вот так выглядит:
https://i.postimg.cc/Hs9sdR3k/blob.png
   Ёпрст
 
7 - 09.10.20 - 23:49
имея id объекта и id реквизита ..и по всем blockno
   Ёпрст
 
8 - 09.10.20 - 23:49
можно заместо update пользовать delete + insert
   Ёпрст
 
9 - 09.10.20 - 23:50
в этом случае.

Да..автора еще ждёт Периодика :)) и знакомство с 1sconst
   Ёпрст
 
10 - 09.10.20 - 23:50
если уж всё заменять
   Ёпрст
 
11 - 09.10.20 - 23:52
и...в документах, в графах отбора, если есть, познакомится с 1crdoc
   MWWRuza
 
12 - 10.10.20 - 09:08
Спасибо. Сегодня буду пробовать.
А длинных строк и периодики - нет. Задача несколько уже, чем у исходной обработки. Мне по большому счету, достаточно "освободить" лишний элемент номенклатуры, перенеся все его движения на "правильный", и потом удалить. Единицы, подчинённые ему - тоже. Регистр остатки, потом пересчитается. Все длинные строки удалятся вместе с ненужным элементом. Единицы, уже на новом владельце, тоже удалить лишние, которые без Шк. А периодика? Ну, только в ценах... Мне проще удалить цены ненужного элемента, вместе с ним, и оставить цены от правильного, свежего элемента... Цены годовалой давности... Ну, моим точно не нужны, ни какой аналитикой мои "лавочники' не занимаются, от слова совсем.
   MWWRuza
 
13 - 11.10.20 - 01:02
(2),(3)
Включил отладку:

UPDATE  
    ra405
SET sp408 = '   3TB   '
FROM ra405 AS Tab
where (Tab.IDDOC = '    2T   ')
 AND  (Tab.sp408 = '    IG   ')
рс.ВыполнитьИнструкцию(ТекстЗапроса);
{D:\BASA_1C\ВЕГА\ЗАМЕНАНОМЕНКЛАТУРЫ.ERT(562)}: FAILED! ICommandText::Execute(): Record is not locked.

Вот... Все равно не меняет. Имя таблицы и идентификаторы, вроде все правильные.
   MWWRuza
 
14 - 11.10.20 - 01:04
Инициализирую запрос так:
                ОлеДБ = СоздатьОбъект("OLEDBData");
                Соединение = "Provider=vfpoledb.1;Mode=ReadWrite;Data Source="+КаталогИБ()+";Collating Sequence=machine;";
                Если ОлеДБ.Соединение(Соединение)=0 Тогда
                    Сообщить("Не соеденились");
                    Возврат;
                КонецЕсли;
                рс = ОлеДБ.СоздатьКоманду();
                
                рс = ОлеДБ.СоздатьКоманду();
                рс.Выполнить("EXECSCRIPT('SET ANSI OFF')");  
                рс.Выполнить("EXECSCRIPT('SET REPROCESS TO 60 SECONDS')");
                рс.Выполнить("EXECSCRIPT('SET REFRESH TO 0,-1')");    
                рс.Выполнить("Exec('SET TABLEVALIDATE TO 0')");
                рс = ОлеДБ.СоздатьКоманду();
   Злопчинский
 
15 - 11.10.20 - 01:36
галактеко волнуецо
   AAA
 
16 - 11.10.20 - 05:37
(14)Сделай сначала не UPDATE, а SELECT, может выборка пустая. Поле SP408 случайно не справочник неопределенного вида ?
   MWWRuza
 
17 - 11.10.20 - 07:32
(16) Нет. Справочник "Номенклатура".
А вот что выборка пустая... Возможно.
Что эта ошибка вообще означает, то, что не может получить доступ на запись, или не спозиционировался на записи?
   MWWRuza
 
18 - 11.10.20 - 07:43
+(17) А не может быть причиной, что я сначала аналогичным запросом таблицу ссылок формирую, а потом, менять пытаюсь? Может после первого запроса, таблица "занята" остаётся?
Попробовать изменить первый запрос, открывать таблицу только на чтение? Или как то принудительно "освобождать" ее?
   Ёпрст
 
19 - 11.10.20 - 09:03
(18) покажи весь код
   Ёпрст
 
20 - 11.10.20 - 09:14
Хотя, не нужен код. Просто открой 1сину НЕ монопольно. Для монопольного режима нужно ставить заплаткутот hogik
   MWWRuza
 
21 - 11.10.20 - 10:31
(20) Не...
Прежде, чем задавать вопросы здесь, я естественно изучил все, что удалось найти поиском по этой проблеме... И про монопольный режим - первое, что выскочило.
Пробовал и в разделенном, и в монопольном - все одинаково. И заплатку от hogik поставил, тоже эффекта нет.
Сейчас проверил свое предположение - в первом запросе, вместо "Mode=ReadWrite;" написал "Mode=Read;", тоже ничего не дало, во всех случаях ошибка та-же.
(19) Показать весь код? Там почти 600 строк, на форум такое выкладывать... Как-то не корректно... Вот ссылка на мою поделку: https://cloud.mail.ru/public/5yzg/4isPPPU9t Там большая часть кода не моя, заимствована отсюда:  http://catalog.mista.ru/public/77355/, с минимальной адаптацией под мои "хотелки"...
   MWWRuza
 
22 - 11.10.20 - 11:56
Тут нечто подобное описано: https://www.1cpp.ru/forum/YaBB.pl?num=1259656140
Попробовал без FROM -
|UPDATE                   
|    $"+тзПотомки.Метаданные+"                 
| SET $"+тзПотомки.Метаданные+"."+тзПотомки.Реквизит +" = :Объект              
//|FROM $"+тзПотомки.Метаданные+" AS Tab                 

|where (Tab.IDDOC = :Док)             
//| AND  ($Tab."+тзПотомки.Реквизит+" = :Источник)                 

| AND  ($"+тзПотомки.Метаданные+"."+тзПотомки.Реквизит+" = :Источник)                 
|";

Получаю:
UPDATE  
    ra405
 SET sp408 = '   3TB   ' 
where (Tab.IDDOC = '    2T   ')
 AND  (sp408 = '    IG   ')
рс.ВыполнитьИнструкцию(ТекстЗапроса);
{D:\BASA_1C\ВЕГА\ЗАМЕНАНОМЕНКЛАТУРЫ.ERT(562)}: FAILED! ICommandText::Execute(): SQL: Column '     ' is not found.

Какую-то колонку не находит почему-то...
Не пойму, таблица - правильная, заменить в ней поле в колонке "sp408" когда идентификатор документа "2T" и значение этого поля "IG"... Какая ему еще колонка нужна?
Может не "sp408" должно быть, а "Tab.sp408" - ?
   MWWRuza
 
23 - 11.10.20 - 12:14
Вот так заработало:
                ТекстЗапроса = "
                |UPDATE
                |    $"+тзПотомки.Метаданные+"
                | SET $"+тзПотомки.Метаданные+"."+тзПотомки.Реквизит +" = :Объект 
            //    |FROM $"+тзПотомки.Метаданные+" AS Tab

            //    |where (Tab.IDDOC = :Док) 

                |where ("+тзПотомки.Метаданные+".IDDOC = :Док)
            //    | AND  ($Tab."+тзПотомки.Реквизит+" = :Источник)

                | AND  ($"+тзПотомки.Метаданные+"."+тзПотомки.Реквизит+" = :Источник)
                |";

В отладке пишет:
UPDATE
    ra405
 SET sp408 = '   3TB   ' 
where (Регистр.ОстаткиТМЦ.IDDOC = '    2T   ')
 AND  (sp408 = '    IG   ')
 - Изменены движения по регистру ОстаткиТМЦ
UPDATE
    ra328
 SET sp331 = '   3TB   ' 
where (Регистр.ПартииНаличие.IDDOC = '    2T   ')
 AND  (sp331 = '    IG   ')
 - Изменены движения по регистру ПартииНаличие

Но, реально ничего не меняет... Повторный поиск ссылок опять их находит.
   MWWRuza
 
24 - 11.10.20 - 12:32
+(23) Ну, да... Проверил файлы, время изменения в 0:15(это я через XBase менял, как внешние, и потом копировал в базу, ради пробы, в выложенной обработке этот кусок закомментирован), а последний раз запускал в 12:25 - файлы не меняются... Хотя пишет, что все изменено и ошибок нет. Может как-то записывать изменения надо?
   MWWRuza
 
25 - 11.10.20 - 13:52
+(23) Я уже и имя параметра "Объект" заменил на "ОбПрием", ничего не меняется.
   Ёпрст
 
26 - 11.10.20 - 21:37
Ё...чего, (2) не осилил ?

На вот, занимайся

            ТекстЗапроса = "
                |UPDATE  
                |    Tab
                | SET $Tab."+тзПотомки.Реквизит +" = :Объект 
                |FROM $"+тзПотомки.Метаданные+" AS Tab
                |where (Tab.IDDOC = :Док)
                | AND  ($Tab."+тзПотомки.Реквизит+" = :Источник)
                |"; 

   MWWRuza
 
27 - 11.10.20 - 22:53
(26) Да, так работает! Спасибо огромное!
   Злопчинский
 
28 - 11.10.20 - 23:08
(27) галактеко вздохнуло с облегчением. темный император повержен
   MWWRuza
 
29 - 25.10.20 - 17:32
Та-же обработка, на другой базе:
Ошибка обработки запроса:

SELECT DISTINCT
    :Объект As [Объект $Справочник.Номенклатура]
    ,Tab.IDDOC As [Ссылка $Документ.Приходная]
    ,'Товар' As Реквизит
    ,'ДокументСтроки.Приходная' As Метаданные 
    
FROM
    $ДокументСтроки.Приходная As Tab 
    
where  $Tab.Товар = :Объект

База данных не установлена

Что значит "База данных не установлена", как это понимать?
   ДенисЧ
 
30 - 25.10.20 - 17:51
 
 Рекламное место пустует
   MWWRuza
 
31 - 25.10.20 - 18:15
Ну... А почему, в другой аналогичной базе работает?
Вот полный текст:
        ДопКолонка = тзРеквизитов.ДопКолонка;
        ДопТаблица = тзРеквизитов.ДопТаблица;
        
        Если тзРеквизитов.ОбъектМетаданных = "Константа" Тогда
            ОбъектМетаданных = "_1SCONST";
        Иначе
            ОбъектМетаданных = "$"+тзРеквизитов.ОбъектМетаданных;
        КонецЕсли;
        
        ТекстЗапроса = "
        |SELECT DISTINCT
        |    :Объект As [Объект $"+ПредТип_Вид+"]
        |    ,"  + тзРеквизитов.Идентификатор+" As " + Типизатор +"
        |    ,'"+ тзРеквизитов.Реквизит+"' As Реквизит
        |    ,'"+ тзРеквизитов.ОбъектМетаданных+"' As Метаданные 
        |    "  + ДопКолонка+"
        |FROM
        |    "+ ОбъектМетаданных+" As Tab 
        |    "+ ДопТаблица + "
        |where "+тзРеквизитов.Условие +"
        |";
        рс.УстановитьТекстовыйПараметр("Объект",ВыбОбъект);
        Попытка
            тзЗапроса = рс.ВыполнитьИнструкцию(ТекстЗапроса); 
        Исключение
            Сообщить("Ошибка обработки запроса: ");
            Сообщить(ТекстЗапроса);
            Сообщить(ОписаниеОшибки());
            Сообщить("--------------------------");
        КонецПопытки;
        Если тзЗапроса.КоличествоСтрок() <> 0 Тогда
            тзСсылок.Объединить(тзЗапроса);
        Иначе
            //Сообщить("В "+СтрЗаменить(тзРеквизитов.ОбъектМетаданных,"Строки","")+ " ссылки не найдены");

        КонецЕсли;
   MWWRuza
 
32 - 25.10.20 - 18:18
Я там ничего специально не устанавливаю... Может это где-то не явно происходит?
   Ёпрст
 
33 - 25.10.20 - 21:01
(29) формат базы то какой хоть? Дбф/скуль
   trdm
 
34 - 25.10.20 - 23:01
(32) РС на скуле автоконектится.
   MWWRuza
 
35 - 25.10.20 - 23:50
(33) Да ничего не поменялось... Обработка та-же, база как и изначально - dbf, компьютер тот-же, соответственно драйвер db установлен.
   Ёпрст
 
36 - 25.10.20 - 23:55
(35) формат базы какой ? dbf/sql ?
   Ёпрст
 
37 - 25.10.20 - 23:56
строка соединения с базой какая ?
   Ёпрст
 
38 - 25.10.20 - 23:57
и.. версия 1cpp какая светится в меню "О программе "?
   MWWRuza
 
39 - 26.10.20 - 00:14
(37) А ни какая... Спасибо, извиняюсь, просто перепутал обработку... Это исходная была, под скуль...
Проверил - а нет строки подключения... И сразу все понятно стало, использовал ту, которую дорабатывал под дбф - и все заработало.


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.