Как правильно проапдейтить/инсертить табличку? Если в ней есть записи ?

Внимание! Тема закрыта. Добавлять сообщения в закрытую тему запрещено.
1. Ёпрст 1063 08.08.14 17:45 Сейчас в теме
Как правильно проапдейтить/инсертить табличку? Если в ней есть записи ?
Вознаграждение за ответ
Показать полностью
Найденные решения
6. trad_ 08.08.14 19:35 Сейчас в теме
обычно пишу так

|UPDATE ...
|IF @@ROWCOUNT = 0
|   INSERT ...

и не парюсь
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
13. pvase 401 11.08.14 13:34 Сейчас в теме
(1) Ёпрст, Есть несколько вариантов.
При наличии поля идентификатора, уникального для всех записей таблицы:
Обычно использовал:
UPDATE ... table1 where ID = <ID>
if @@rowcount = 0 
INS ERT IN TO table1 ...

но это работает для одной записи. Если вставить/обновить надо несколько записей, тогда лучше или их перебирать, или же сделать UPDATE и проверить @@rowcount чтобы был равным количеству обновляемых записей. Если @@rowcount меньше - тогда делать INSERT недостающих.
Если же уникального поля в таблице нет, тогда надо сравнивать все столбцы, и то не факт что не будет изменен дубль (если такой имеется в таблице).

p.s. Удивлен что вы спрашиваете такой вопрос :).
14. Ёпрст 1063 11.08.14 13:46 Сейчас в теме
(13) спасибо конечно, но всё это...на хрен не нужно.
:)
Вопрос вообще не в 1с и не за этим.
17. pvase 401 11.08.14 14:34 Сейчас в теме
(14) Ёпрст, А о какой таблице идет речь? Апдейт и Инсерт это как бы связано с SQL, или я чего то пропустил?
18. Ёпрст 1063 11.08.14 14:49 Сейчас в теме
2. Cooler 22 08.08.14 17:52 Сейчас в теме
Ёпрст, что-то спрашивающий про 7.7? Мир перевернулся...
3. Ёпрст 1063 08.08.14 17:54 Сейчас в теме
4. Cooler 22 08.08.14 18:00 Сейчас в теме
Ааа... Ну, тогда ждем счастливчика!
5. jobkostya1c_ERP 100 08.08.14 19:30 Сейчас в теме
Я понимаю был бы вопрос на засыпку и для 1С 8: как правильно удалить строчки из таблицы значений.
7. Allexe8.1 08.08.14 21:14 Сейчас в теме
(5) kostyaomsk, и скорее всего, будете не правы. Потому что в 1с8 строки в таблице значений - удаляются по внутренним идентификаторам, а не по индексу. Можете проверить) Но для массива - будет справедливо - элементы из массива удаляются "снизу-вверх"
Зы. собственно это делает возможным определение ошибки что-то там "нельзя изменить строку таблицы значений, т.к. она была удалена". Строка таблицы значений "знает" о своем контейнере (метод Владелец()) - элемент массива же, в отличие от - о массиве ничего не "знает"
8. jobkostya1c_ERP 100 10.08.14 14:53 Сейчас в теме
(7) Allexe8.1, если коснуться вопроса именно удаления строк в ТаблицеЗначений 1С 8, то если действовать методом построчного перебора с анализом нужно идти снизу вверх. Для примера создал обработку с целью иллюстрации правильного и неправильного варианта удаления. Далее привожу фрагмент правильного и неправильного метода "перебора".
Правильный:

// Исходные данные ТЗ - таблица значений в которой есть колонка "ФлагУдаления" тип булево.
	// Допустим, в таблице значений 5 строк
	МаксИнд = ТЗ.Количество()-1; // Вычисляем максимальный индекс строки (в нашем случае 4)
	Для Инд=0 По МаксИнд Цикл
		// Внутри цикла основной счетчик Инд будет последовательно принимать значения 
		// от 0 До МаксИнд: 0, 1, 2, 3, 4. 
		УбывающийСчетчикИндекс = МаксИнд - Инд; // Будет принимать значения: 4, 3, 2, 1, 0
		// Получаем очередную строку таблицы снизу вверх по вспомогательному убывающему индексу
		СтрТЗ = ТЗ[УбывающийСчетчикИндекс]; // Переменная СтрТЗ содержит ссылку на строку таблицы значений
		// Проверяем строку на условие удаления по условию ее колонки "ФлагУдаления"
		Если СтрТЗ.ФлагУдаления Тогда
			ТЗ.Удалить(УбывающийСчетчикИндекс); //
			// Теперь и в переменной СтрТЗ 
			Сообщить ("Удалили строку с индексом "+Инд); // 
		Иначе
			Сообщить ("Строка с индексом "+инд+" оставлена");
		КонецЕсли;	
	КонецЦикла;	
Показать

Неправильный (в лучшем случае не отработает корректно, в худшем ошибка периода исполнения при выходе индекса за границу диапазона при движении сверху вниз по таблице значений):
МаксИнд = ТЗ.Количество()-1; // Вычисляем максимальный индекс строки (в нашем случае 4)
	Для Инд=0 По МаксИнд Цикл
		СтрТЗ = ТЗ[Инд]; 
		// Проверяем строку на условие удаления по условию ее колонки "ФлагУдаления"
		Если СтрТЗ.ФлагУдаления Тогда
			ТЗ.Удалить(Инд); //
			Сообщить ("Удалили строку с индексом "+Инд); 
		Иначе
			Сообщить ("Строка с индексом "+инд+" оставлена");
		КонецЕсли;	
	КонецЦикла;	
Показать

Естественно, можно использовать более мощный метод ТЗ.НайтиСтроки(...), Поместить таблицу значений в запрос и прочее, но интерес представляет понятие "Внутренний идентификатор строки таблицы значений". Так полагаю ГУИД имеет смысл для тех данных что есть в базе (все что хранится в ее таблицах) + ГУИДы объектов метаданных конфигурации, еще ключ уникальности для форм, а вот для строк таблицы значений? Может быть как-то в ОЗУ при выполнении в среде 1С 8 есть какие-то служебные идентификаторы?
И еще один инетересный момент
в 1с8 строки в таблице значений - удаляются по внутренним идентификаторам, а не по индексу.
Это что означает. Наверное про непосредственное удаление средствами SQL?
А насчет утверждения
собственно это делает возможным определение ошибки что-то там "нельзя изменить строку таблицы значений, т.к. она была удалена". Строка таблицы значений "знает" о своем контейнере (метод Владелец()) - элемент массива же, в отличие от - о массиве ничего не "знает"

тут действительно получается что при срабатывании метода таблицы значений
ТЗ.Удалить(Индекс)
переменная СтрТЗ где хранилась строка таблицы значений как-бы "помнит" структуру, но данных в ней уже нет.
Привожу обработку для тестирования удаления строк из таблицы значений и результаты работы отладчика при тестировании значений переменной строки таблицы значений и ее метода
СтрТЗ.Владелец()
. В документации пишут что данный метод имеет практический смысл только для дерева значений. Какой смысл получается от него для таблицы значений?
Прикрепленные файлы:
УдалениеСтрокИзТЗ.epf
9. Allexe8.1 10.08.14 17:44 Сейчас в теме
(8) kostyaomsk, если по индексу, то да, нужно снизу вверх, равно как и с массивом. При получении элементов по индексу - вы каждый раз получаете следующий элемент, при использовании "Для Каждого Из" - работаете со всей коллекцией. И в этом случае ошибки не будет.
....
Владелец()
Возвращаемое значение:
Тип: ТаблицаЗначений.
Описание:
Получает владельца данной строки.


По поводу внутр. идентификатора строки ТЗ - ошибся, вся информация о строках ТЗ - находится в самом объекте ТЗ.
Поэтому, например, "ЗначениеВСтрокуВнутр(ТЗ[0]) = ЗначениеВСтрокуВнутр(ТЗ[1])"
6. trad_ 08.08.14 19:35 Сейчас в теме
обычно пишу так

|UPDATE ...
|IF @@ROWCOUNT = 0
|   INSERT ...

и не парюсь
10. jobkostya1c_ERP 100 10.08.14 20:04 Сейчас в теме
Верно, забыл про сериализацию таблицы значений. Но это уже к клиент-серверному взаимодействию относится. Если уж в тонком клиенте нельзя создать Объект ТаблицаЗначений на клиентской стороне из-за громоздкости, то передать его в виде текста в сериализованном виде можно. Один раз из практике хотели вывести ошибки при проведении документа, но не стали использовать этот вариант. Обычно имеет смысл тех объектов, которые уже есть в базе (документы) и, как правило, для обмена данными.
А раз уж начали эту тему в подробностях про ТаблицуЗначений добавлю код:
А = ЗначениеВСтрокуВнутр(ТЗ[0]);
Б = ЗначениеВСтрокуВнутр(ТЗ[1]);
С = ЗначениеВСтрокуВнутр(ТЗ);

Из справки:
Глобальный контекст (Global context)
ЗначениеВСтрокуВнутр (ValueToStringInternal)
Синтаксис:
ЗначениеВСтрокуВнутр(<Значение>)
Параметры:
<Значение> (обязательный)
Тип: Произвольный.
Преобразуемое значение.
Возвращаемое значение:
Тип: Строка.
Системное представление значения в информационной базе.
Описание:
Получает системное строковое представление переданного значения.
В отладчике:
Прикрепленные файлы:
11. Allexe8.1 10.08.14 22:22 Сейчас в теме
(10) kostyaomsk, в общем забавно получается:
Попробовал следующим кодом пройтись в отладчике:
ТЗ = Новый ТаблицаЗначений;
	ТЗ.Колонки.Добавить("Колонка");
	
	Стр1 = ТЗ.Добавить();
	Стр1.Колонка = 555;
	Стр2 = ТЗ.Добавить();
	Стр2.Колонка = 777;
	Стр3 = ТЗ.Добавить();
	Стр3.Колонка = 999;
	
	ВнутрСтрока1 = ЗначениеВСтрокуВнутр(ТЗ);
	ТЗ.Удалить(Стр2);
	ВнутрСтрока2 = ЗначениеВСтрокуВнутр(ТЗ);
Показать


Получилось, что, до удаления, т.е ВнутрСтрока1 =
{"#",acf6192e-81ca-46ef-93a6-5a6968b78663,
{8,
{1,
{0,"Колонка",
{"Pattern"},"",0}
},
{2,1,0,0,
{1,3,
{2,0,1,
{"N",555},0},
{2,1,1,
{"N",777},0},
{2,2,1,
{"N",999},0}
},0,2}
}
}
Показать

После удаления, ВнутрСтрока2 =
{"#",acf6192e-81ca-46ef-93a6-5a6968b78663,
{8,
{1,
{0,"Колонка",
{"Pattern"},"",0}
},
{2,1,0,0,
{1,2,
{2,0,1,
{"N",555},0},
{2,2,1,
{"N",999},0}
},0,2}
}
}
Показать


Обратите внимание на последовательность символов "{2,0,1,{"N",555},0}", "{2,2,1,{"N",999},0}"
Можно, предположить, что это и есть строка ТЗ. Причем видно, что "{2,1,1,{"N",777},0}" - после удаления исчезло из внутреннего представления. Скорее всего выделенные символ "{2,0,1", {2,1,1" и есть идентификаторы строк ТЗ. Собственно, поэтому при использования Для Каждого Из - индексы "не сбиваются" при удалении строк. Кстати, еще интересный вывод. Передавая, например, в функцию строку ТЗ, мы на самом деле передаем всю таблицу значений (точнее, указатель)
12. ivsher 11.08.14 11:16 Сейчас в теме
Извините конечно за флуд, но как тема удаления строк из таблиц 1с8 касается использования прямых запросов для обновления таблиц 1с7.7???
Мне вот лично было бы интересно почитать сообщения касающиеся темы, а найти их, с учетом ваших постов, очень сложно. Пожалуйста,создайте отдельную тему в соответствующей ветке, и там пишите.
15. Ёпрст 1063 11.08.14 13:47 Сейчас в теме
а как обновить записи, я и сам кому хошь покажу..
16. AlexInqMetal 77 11.08.14 13:50 Сейчас в теме
(15) Ёпрст, закрыл бы тему...
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот