(6) Типовой из КД «Перенос остатков товара» =)
Запрос = Новый запрос();
Запрос.текст = «ВЫБРАТЬ
| ОстаткиТоваровНаСкладахОстатки.Номенклатура КАК Номенклатура,
| ОстаткиТоваровНаСкладахОстатки.КоличествоОстаток КАК Количество
| ИЗ
| РегистрНакопления.ОстаткиТоваровНаСкладах.Остатки КАК ОстаткиТоваровНаСкладахОстатки»;
Выборка = запрос.Выполнить().Выбрать();
ТоварыНаСкладах = Новый ТаблицаЗначений();
ТоварыНаСкладах.Колонки.Добавить(«Номенклатура»);
ТоварыНаСкладах.Колонки.Добавить(«Количество»);
ТоварыНаСкладах.Колонки.Добавить(«Период»);
ДатаВыгрузки = ТекущаяДата();
Пока Выборка.Следующий() Цикл
СтрокаТоваров = ТоварыНаСкладах.Добавить();
СтрокаТоваров.Номенклатура = Выборка.Номенклатура;
СтрокаТоваров.Количество = Выборка.Количество;
СтрокаТоваров.Период = ДатаВыгрузки;
КонецЦикла;
ТаблицаИменРегистров = Новый ТаблицаЗначений();
ТаблицаИменРегистров.Колонки.Добавить(«Имя»);
ТаблицаИменРегистров.Колонки.Добавить(«Представление»);
СтрокаТаблицы = ТаблицаИменРегистров.Добавить();
СтрокаТаблицы.Имя = «ОстаткиТоваровНаСкладах»;
СтрокаТаблицы.Представление = «Остатки товаров на складах»;
ИсходящиеДанные = Новый Структура;
ИсходящиеДанные.Вставить(«Номер», «001»);
ИсходящиеДанные.Вставить(«Дата», ДатаВыгрузки);
ИсходящиеДанные.Вставить(«Комментарий», «Перенос остатков товаров на » + Строка(ДатаВыгрузки));
ИсходящиеДанные.Вставить(«ТаблицаРегистровНакопления», ТаблицаИменРегистров);
ИсходящиеДанные.Вставить(«ОстаткиТоваровНаСкладах», ТоварыНаСкладах);
ВыгрузитьПоПравилу(, , ИсходящиеДанные, , «ПереносОстатковТоваров»);
|
Гость 0 — 02.11.2015 — 14:36 |
Добрый день. Переношу сильно дописанную Тис в не менее дописанную УТ Выгружаю один справочник. В восьмерке есть таб часть ТОВАРЫ, в 77 есть реквизит КодыТоваров — строка, в которой лежат коды товаров. В правилах у этого справочника создаю Группу свойств. Источник — пустой, Приемник — Товары. Так же создаю свойство Приемник-Номенклатура Пытаюсь выгрузить этот справочник. Получаю ошибку «Ошибка выбора объектов коллекции» Я в ступоре. Лезу в код обработки выгрузки. Вижу что семерка пытается получить свойство: Объект.ТОВАРЫ — но почему она это делает??? Если убрать таблицу свойств, то справочник грузится. Подскажите где я ступил. Уж голова кипит от этих правил. |
|
|
Гость 1 — 02.11.2015 — 14:53 |
Эффект присутствия млин.
|
|
|
Гость 2 — 02.11.2015 — 19:21 |
Это все гребаный шайтан «Одноес Нуралиеч» дарующий иногда «ТАк и не понял почему первый раз не заработало».
|
|
|
Гость 3 — 02.11.2015 — 20:18 |
2-Сли то > Не нервничай. В России 2 беды: тся и ться. |
ПВД: Вылетает ошибка из сабжа. Что не так?
Вообще — много непонятного
Данные, выгружаемые по правилу — ПЕРВЫЙ параметр.
ВыгрузитьПоПравилу(ИсходящиеДанные,,,, «КорректировкаЗаписейРегистров»); — Та же самая ошибка. А вообще из примера взял, в примере «Исходящие данные» задаются 3 параметром, а первый пустой.
Где вы, ять, такие примеры берете?
Типовой из КД «Перенос остатков товара» =) Запрос = Новый запрос; СтрокаТаблицы.Представление = «Остатки товаров на складах»; ИсходящиеДанные.Вставить(«Комментарий», «Перенос остатков товаров на » + Строка(ДатаВыгрузки));
В справке к КД такого нет, я гарантирую это.
Ну да, в справке по-другому. Но и если первым параметром указывать, то та же самая ошибка.
Ошибка какбе символизирует нам, что КД ожидает увидеть в неком свойстве коллекцию. А у тебя там ХЗ что.
В это некое свойство я передаю ТЗ. ТЗ не пустая однозначно. ТЗ же является коллекцией, правильно?
Рекомендую таки изучить правило под лупой. Что-то ты там делаешь не так
Вы пытаетесь передать Объект, который хотите, чтобы конвертация обошла как коллекцию, из которой выбрала Объект
протупил я, смотри в отладчике, в 7 проще чем в 8
Вообщем, получилось выгруэить все же вот так: То есть ТЗ передать 3 параметром. при этом в ПВД очистил поле «Правило конвертации».
Тэги: 1С 8
Комментарии доступны только авторизированным пользователям
Показывать по
10
20
40
сообщений
Новая тема
Ответить
sidhartha
Дата регистрации: 13.08.2009
Сообщений: 38
Acc77_80.xml»;Обработки взял с июльского ИТС. Решил сначала потренироваться на стандартной демо-базе 7.70.507 без изменения правил. Галочку оставил у одного простого справочника — «расходы будущих периодов», потом попробовал «ценные бумаги». Все равно ошибка. Это вообще работает?<br><br><br>Ошибка исполнения обработчика: Конвертация_ПередВыгрузкойДанных<br> — Поле агрегатного объекта не обнаружено (ДатаКонцаПериодаВыгрузки)<br>Ошибка исполнения обработчика: ПКО_ПередВыгрузкой_Работники<br> — Значение не представляет агрегатный объект (КоличествоСтрок)<br>Ошибка получения значения свойства объекта<br> Объект: Основной р/с, свойство: ВалютаДенежныхСредств.<br>Ошибка исполнения обработчика: ПКС_ПередВыгрузкой_Работники_Дата_Свойство9<br> — Поле агрегатного объекта не обнаружено (ДатаКонцаПериодаВыгрузки)<br>ПКГС_ПередОбработкойВыгрузки_Работники_РаботникиОрганизаций_ТабличнаяЧасть1<<?>>(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, КоллекцияОбъектов, НеЗамещать, НеОчищать)<br>Функция не обнаружена (ПКГС_ПередОбработкойВыгрузки_Работники_РаботникиОрганизаций_ТабличнаяЧасть1)<br>Ошибка выбора объектов коллекции<br>ПКС_ПередВыгрузкой_Работники_ВидЗанятости_Реквизит13<<?>>(Источник, Приемник, ВходящиеДанные, ИсходящиеДанные, НомерПКС, НомерПКО, ОбъектКоллекции, Значение, ТипПриемника, ИмяПКО, ИмяПКОВидСубконто, Пусто, Выражение, НеЗамещать)<br>Функция не обнаружена (ПКС_ПередВыгрузкой_Работники_ВидЗанятости_Реквизит13)<br>Ошибка исполнения обработчика: ПКО_ПередВыгрузкой_УволенныеРаботники<br> — Значение не представляет агрегатный объект (КоличествоСтрок)
Показывать по
10
20
40
сообщений
Особенности переноса данных в «1С-КАМИН:Зарплата. Версия 5.0»:
Данные по начислениям, отработанному времени и периодам невыходов на дату начала выгрузки переносятся в документ «Входящее сальдо».
Например — при выгрузке задается период с 01.01.2019 года.
ВНИМАНИЕ! База и неотработанное время для расчета больничных и по среднему переносится в документ «Входящее сальдо». Рекомендуем указывать в качестве периода переноса — начало текущего года.
Данные (начисления, периоды невыходов за 2017 и 2018 год и сальдо на 01.01.2019) будут выгружены в документ «Входящее сальдо».
Данные (начисления и удержания) с 2019 года выгружаются полностью в соответствующие документы. Внимание: данные по невыходам (больничные, отпускные и т.п.) переносятся в документ «Регистрация невыходов».
Параметры выгрузки.
Варианты выгрузки в соответствующих параметрах:
— Выгружать полностью все (все справочники, кадры, начисления и т.д.);
— выгружать только справочники и кадровые документы;
— выгружать справочники, кадровые документы и входящее сальдо (не будут переносится документы за текущий период).
Остальные параметры:
— Выгружать во «Входящее сальдо» один год. В документ Входящее сальдо будут выгружены сведения по начислениям, отработанному и неотработанному времени только за один предшествующий год.
-Удержан НДФЛ за декабрь. Устанавливается, если выплата ЗП и соответственно удержание НДФЛ за декабрь было произведено в декабре.
— Не выгружать уволенных на дату начала переноса. При установленном параметре не будут переносится сотрудники и связанные с ними документы, если они были уволены ранее даты начала переноса и по ним нет задолженностей по зп (сальдо).
— Оставлять коды Сотрудников. Оставляет нумерацию элементов справочника Сотрудники.
— Переносить Источники доходов. Если предполагается использование источников дохода в 5.0, то устанавливается в значение ДА.
По ошибкам и логу конкретно невозможно определить, в чем проблема. Вероятно проблема при выгрузке сальдо по НДФЛ во Входящее сальдо. Но все же нужно смотреть саму информационную базу 2.0
Есть ли способ выбрать / заполнить коллекцию Oracle (« ТАБЛИЦА ») при обычном выборе из jdbc, то есть без процедуры с объявленной переменной для массового сбора или анонимного блока в Oracle12c ?
Проблема заключается в выборе объектов с помощью коллекции объектов, поскольку я не могу найти способ заполнить коллекцию, и поэтому он помещает каждый объект в отдельную коллекцию вместо того, чтобы собирать их в одну (т.е. «запрос с одной строкой вернул более одного ряд»).
Длинная история: Большинство наших сервисов / API имеют параметры динамического поиска, а затем они переводятся в операторы SQL.
Java-код анализирует ограниченный «поиск / где», дезинфицирует и параметризует их, а затем выбирает объекты из oracle, поэтому в большинстве случаев он выполняется намного быстрее, чем жесткий синтаксический анализ oracle, однако я не могу найти решение для заполнения объектов со списком объектов.
Текущая работа — это вызов процедур и предоставление им возможности выполнять массовый сбор объявленных объектов с последующим их возвратом, однако из-за динамического характера предложения «поиск» большинство из них выполняет EXECUTE IMMEDIATE , что является довольно тяжелым для ЦП базы данных.
Другие решения, такие как несколько запросов для каждой строки для выборки этого списка или левое соединение и выборка всего за один ResultSet, просто увеличивают время экспоненциально, поскольку выборка обычно выполняется для огромного количества столбцов, строк и вложенных списков: <
CREATE OR REPLACE TYPE SUB_TYPE_OBJ Force AS OBJECT
(
SVAR1 VARCHAR2(100 CHAR);
SVAR2 DATE,
SVAR3 VARCHAR2(100 CHAR)
);
CREATE OR REPLACE TYPE SUB_TYPE_LST IS TABLE OF SUB_TYPE_OBJ;
CREATE OR REPLACE TYPE MAIN_TYPE_OBJ Force AS OBJECT
(
MVAR1 VARCHAR2(100 CHAR),
MVAR2 VARCHAR2(100 CHAR),
MVAR3 SUB_TYPE_OBJ,
MVAR4 SUB_TYPE_LST
);
SELECT MAIN_TYPE_OBJ (
tab1.val1,
tab1.val2,
(SELECT SUB_TYPE_OBJ( table2.val1, table2.val2, table2.val3) obj FROM table2 WHERE tab1.val1 = tab2.val1),
(SUB_TYPE_LST ( (SELECT SUB_TYPE_OBJ( table3.val1, table3.val2, table3.val3) obj FROM table3 DYNAMIC_WHERE_WITH_LIMITED_FUNCTIONALITY)))
/* if it return more than one row everything breaks :( */
), CNT
FROM (
SELECT table1.*, COUNT(*) OVER(table1.val1) AS CNT FROM table1
WHERE DYNAMIC_WHERE_WITH_LIMITED_FUNCTIONALITY
ORDER BY val1 ASC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY) tab1;
Если table3 возвращает более одной строки, мы получаем «однострочный запрос возвратил более одной строки», потому что я просто создаю группу списков вместо одного, содержащего все объекты, но я не могу понять, как это сделать;
Любые идеи приветствуются, но, пожалуйста, пока исключите DBMS_SQL или NoSQL :).
3 ответа
На самом деле у EXECUTE IMMEDIATE есть using_clause , который позволяет передавать переменные привязки
Чтобы адаптировать пример @Bob, простая настройка
strQuery := 'SELECT * FROM DATA_TABLE WHERE ' || strField_name || '= :x' ;
EXECUTE IMMEDIATE strQuery BULK COLLECT INTO colVals USING nField_val;
Это создает инструкцию SQL с переменной связывания, которая подвергается только мягкому синтаксическому анализу .
SELECT * FROM DATA_TABLE WHERE FIELD1= :x
Конечно, у этого подхода есть ограничение, количество переменных связывания является статическим , определенным как список в операторе EXECUT EIMMEDIATE, например USING a,b,c,d,e
На ум приходят две проблемы . Первый — это необязательные параметры , т. Е. Некоторые запросы выполняют поиск по name, а birth_date некоторые только по name
Вы можете найти множество решений с OR или NVL, например здесь или здесь, но превосходное решение, популяризированное Томом Кайтом, использовало трюк быстрого доступа 1=1 OR:
Если используется переменная связывания, вы создаете ее в предложении WHERE
birth_date = :birth_date
Если он не используется , вы избавитесь от него, создав следующий предикат
(1=1 or :birth_date is NULL)
Эффект таков: 1) количество связываемых переменных остается фиксированным (даже если: Birth_date не используется) и 2) оценка 1=1 как true пропустит остальную часть предиката, т. Е. переменная привязки не действует.
Вторая проблема связана со списками IN , которые могут иметь динамическое количество членов; от 1 до 1000 на Oracle.
эталонный тест — это решение Hibernate, которое подсчитывает длину списка IN и генерирует соответствующий динамический SQL, например col1 in (?,?,?,?) для четырех мебмеров в списке IN. В итоге вы получаете до 1000 жестко проанализированных SQL-запросов (по одному на каждую длину), но в любом случае это логарифмическое улучшение по сравнению с наихудшим случаем вставки списка в динамический SQL .
Из ограничения, описанного выше, вы уже знаете, что это невозможно с помощью EXECUTE IMMEDIATE (и вам нужно будет узнать что-то новое;), например DBMS_SQL)
Вы можете попробовать уловку и ограничить список IN, скажем, 10 участниками и заполнить его NULL s.
Т.е. чтобы передать 4 члена, вы свяжете следующие переменные:
col1 IN (1,2,3,4,null,null,null,null,null,null)
Но обратите внимание, что я не знаю, будет ли производительность в длинном списке IN (для короткого списка IN это будет работать нормально). Кроме того, этот подход окончательно не работает для col1 NOT IN, которые ничего не возвращают, если в списке IN есть NULL.
0
Marmite Bomber
26 Авг 2019 в 11:01
Здесь у вас есть несколько вариантов. Вы можете открыть свой запрос как явный курсор, а затем FETCH … BULK COLLECT INTO соответствующую коллекцию; вы можете использовать EXECUTE IMMEDIATE … BULK COLLECT INTO; или, как вы говорите, вы не хотите слышать, вы можете использовать DBMS_SQL.
Чтобы использовать EXECUTE IMMEDIATE … BULK COLLECT, вы должны использовать что-то вроде
CREATE TABLE DATA_TABLE(FIELD1 NUMBER,
FIELD2 VARCHAR2(100));
INSERT INTO DATA_TABLE (FIELD1, FIELD2)
SELECT 1, 'ONE' FROM DUAL UNION ALL
SELECT 1, 'TWO' FROM DUAL UNION ALL
SELECT 2, 'THREE' FROM DUAL UNION ALL
SELECT 2, 'FOUR' FROM DUAL UNION ALL
SELECT 3, 'LAST' FROM DUAL;
DECLARE
TYPE typeCol IS TABLE OF DATA_TABLE%ROWTYPE;
colVals typeCol;
strField_name VARCHAR2(30) := 'FIELD1';
nField_val NUMBER := 2;
strQuery VARCHAR2(4000);
BEGIN
strQuery := 'SELECT * FROM DATA_TABLE WHERE ' || strField_name || '=' || nField_val;
DBMS_OUTPUT.PUT_LINE(strQuery);
EXECUTE IMMEDIATE strQuery BULK COLLECT INTO colVals;
FOR i IN colVals.FIRST..colVals.LAST LOOP
DBMS_OUTPUT.PUT_LINE(i || ': FIELD1=' || colVals(i).FIELD1 || ' FIELD2=' || colVals(i).FIELD2);
END LOOP;
END;
/
dbfiddle здесь
документы здесь (с 10.1 — лучше, чем более поздние версии IMO)
1
Bob Jarvis — Reinstate Monica
25 Авг 2019 в 21:13
Просто используйте EXTEND, чтобы добавить новую строку в коллекцию!
Прежде всего создайте локальный varabile (например, one_row), который будет указывать на структуру вашей коллекции после этого:
SUB_TYPE_LST.extend;
one_row.SVAR1 := 'VALUE1';
one_row.SVAR2 := sysdate;
one_row.SVAR3 := 'value2';
SUB_TYPE_LST(1) := one_row; -- 1 - number of row in the table - you can put a variable which will be incremented inside a loop
0
t v
26 Авг 2019 в 12:38