powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Ошибка - слишком длинная процедура
8 сообщений из 58, страница 3 из 3
Ошибка - слишком длинная процедура
    #39538847
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvladОни все-таки не совсем одинаковые. В первой джойн идет с таблицей iwn, во второй - с таблицей e.
Во второй есть строка WHERE e.show_in_report = ''Y''.
Это не важно, бОльшая часть подзапроса одинаковая, а это значит что её можно вынести в константу.
Ну а переход на SP гораздо симпатичнее и удобнее править в дальнейшем
...
Рейтинг: 0 / 0
Ошибка - слишком длинная процедура
    #39538848
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBrsvnvladпока не очень понимаю, или туплю, если вместо внутреннего скалярного подзапроса вставить хранимку с параметрами, то как осуществлять ее вызов
Весь нужный запрос пишется в хранимой процедуре, а из Delphi вызывается эта хранимка
А если саму хранимку написать с использованием вложенных хранимок, чтобы не писать один и тот же код много раз, там ведь есть много больших повторяющихся кусков (получение скалярных значений). Уже понял, что надо функцию писать, а не процедуру. А как с передачей в нее параметров внешнего запроса? То, что заменило бы джойн с внешним запросом.
...
Рейтинг: 0 / 0
Ошибка - слишком длинная процедура
    #39538859
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvladкак с передачей в нее параметров внешнего запроса? То, что заменило бы джойн с внешним запросомне уверен что понял о чем речь но можно предварительно напихать в отдельную соединяемую таблицу(-ы) (по вкусу временную или gtt) что требуется
...
Рейтинг: 0 / 0
Ошибка - слишком длинная процедура
    #39538873
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vavansvnvladкак с передачей в нее параметров внешнего запроса? То, что заменило бы джойн с внешним запросомне уверен что понял о чем речь но можно предварительно напихать в отдельную соединяемую таблицу(-ы) (по вкусу временную или gtt) что требуется

Вот это
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
  '(SELECT '#13#10 +
  // 1 район

// подзапрос
  'ROUND('#13#10 +
  'IFNULL((SELECT COALESCE(SUM(iwn.sum_rub), 0) '#13#10 +
  'FROM invoicing_working_norm iwn '#13#10 +
  'INNER JOIN contract_working_norm_rate cwnr ON cwnr.id = iwn.contract_working_norm_rate_id '#13#10 +
  'INNER JOIN additional_service a1 ON a1.id = cwnr.service_id '#13#10 +
  'INNER JOIN report_code rc1 ON rc1.id = a1.report_code_id '#13#10 +
  'INNER JOIN invoicing i ON i.id = iwn.invoicing_id '#13#10 +
  'INNER JOIN cargo_zone cz1 ON cz1.id = i.cargo_zone_id '#13#10 +
  'LEFT JOIN invoice_type it ON it.id = i.invoice_type_id '#13#10 +
  'INNER JOIN contract_cargo_head cch1 ON cch1.id = i.contract_cargo_head_id '#13#10 +
  'INNER JOIN contract c1 ON c1.id = cch1.contract_id '#13#10 +
  'INNER JOIN cargo_nomenclature cn ON cn.id = cch1.cargo_id '#13#10 +
  'WHERE UPPER(it.invoice_type_name) IN (''ИМПОРТ'', ''ЭКСПОРТ'', ''КАБОТАЖ'') '#13#10 +
  'AND i.cooperated = ''Y'' '#13#10 +
  'AND c1.cargo_status = pcp.cargo_status '#13#10 +
  'AND cn.cargo_group_id = cg.id '#13#10 +
  'AND i.cargo_zone_id = cz.id '#13#10 +
  'AND cz1.cargo_zone_number = ''1'' '#13#10 +
  'AND i.invoicing_date BETWEEN :date_from AND :date_to '#13#10 +
  'AND UPPER(rc1.report_code_name) = ''ПЕРЕГРУЗКА''), 0) '#13#10 +
  '+ '#13#10 +
  'IFNULL((SELECT COALESCE(SUM(e.sum_rub), 0) '#13#10 +
  'FROM invoicing_additional_service_editing e '#13#10 +
  'INNER JOIN additional_service a ON a.id = e.service_id '#13#10 +
  'INNER JOIN report_code rc ON rc.id = a.report_code_id '#13#10 +
  'INNER JOIN invoicing i ON i.id = e.invoicing_id '#13#10 +
  'INNER JOIN cargo_zone cz1 ON cz1.id = i.cargo_zone_id '#13#10 +
  'LEFT JOIN invoice_type it ON it.id = i.invoice_type_id '#13#10 +
  'INNER JOIN contract_cargo_head cch1 ON cch1.id = i.contract_cargo_head_id '#13#10 +
  'INNER JOIN contract c1 ON c1.id = cch1.contract_id '#13#10 +
  'INNER JOIN cargo_nomenclature cn ON cn.id = cch1.cargo_id '#13#10 +
  'WHERE e.show_in_report = ''Y'' '#13#10 +
  'AND UPPER(it.invoice_type_name) IN (''ИМПОРТ'', ''ЭКСПОРТ'', ''КАБОТАЖ'') '#13#10 +
  'AND i.cooperated = ''Y'' '#13#10 +
  'AND c1.cargo_status = pcp.cargo_status '#13#10 +
  'AND cn.cargo_group_id = cg.id '#13#10 +
  'AND i.cargo_zone_id = cz.id '#13#10 +
  'AND cz1.cargo_zone_number = ''1'' '#13#10 +
  'AND i.invoicing_date BETWEEN :date_from AND :date_to '#13#10 +
  'AND UPPER(rc.report_code_name) = ''ПЕРЕГРУЗКА''), 0) '#13#10 +
  ', 2) AS sum_fact_prr_1, '#13#10 +

...
//таких подзапросов еще 18
...

  'FROM plan_cargo_processing pcp '#13#10 +
  'INNER JOIN cargo_group cg ON cg.id = pcp.cargo_group_id '#13#10 +
  'INNER JOIN cargo_zone cz ON cz.id = pcp.cargo_zone_id '#13#10 +
  'WHERE pcp.cooperated = ''Y'' '#13#10 +
  'AND pcp.year = :year '#13#10 +
  'AND pcp.month = :month ');



Преобразовать вот в это
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
  '(SELECT '#13#10 +
  // 1 район

// подзапрос
  MyStoredFunction('Y', pcp.cargo_status, cg.id, '1', :date_from, :date_to, 'ПЕРЕГРУЗКА') AS sum_fact_prr_1,
...
//таких подзапросов еще 18
...
  MyStoredFunction('Y', pcp.cargo_status, cg.id, '1', :date_from, :date_to, 'ТЭО') AS sum_fact_teo_1,
  MyStoredFunction('Y', pcp.cargo_status, cg.id, '1', :date_from, :date_to, 'ДРУГИЕ') AS sum_fact_other_1
...

  'FROM plan_cargo_processing pcp '#13#10 +
  'INNER JOIN cargo_group cg ON cg.id = pcp.cargo_group_id '#13#10 +
  'INNER JOIN cargo_zone cz ON cz.id = pcp.cargo_zone_id '#13#10 +
  'WHERE pcp.cooperated = ''Y'' '#13#10 +
  'AND pcp.year = :year '#13#10 +
  'AND pcp.month = :month ');


Корректно?
...
Рейтинг: 0 / 0
Ошибка - слишком длинная процедура
    #39538885
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvlad, мне столько не выпить чтоб подобные портяны разбирать, даже с учетом что я ночью улетаю на конфу по smartdata. соорудил бы примитивную демонстрацию что ли для разнообразия
...
Рейтинг: 0 / 0
Ошибка - слишком длинная процедура
    #39539272
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vavansvnvlad, мне столько не выпить чтоб подобные портяны разбирать, даже с учетом что я ночью улетаю на конфу по smartdata. соорудил бы примитивную демонстрацию что ли для разнообразия

Функция:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
CREATE DEFINER = 'cargoport'@'%' FUNCTION `profit_coop_yn`(
        `p_cargo_status` ENUM('export','import','domestic'),
        `p_cargo_group_id` INTEGER(11) UNSIGNED,
        `p_cargo_zone_id` INTEGER(11) UNSIGNED,
        `p_cargo_zone_number` VARCHAR(40),
        `p_invoicing_date_from` DATETIME,
        `p_invoicing_date_to` DATETIME,
        `p_report_code_name` VARCHAR(20),
        `p_cooperated` ENUM('Y','N')
    )
    RETURNS DECIMAL(11,2)
    NOT DETERMINISTIC
    READS SQL DATA
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
  DECLARE val DECIMAL(11,2);
  
  SELECT
  ROUND(
  IFNULL((SELECT COALESCE(SUM(iwn.sum_rub), 0)
  FROM invoicing_working_norm iwn
  INNER JOIN contract_working_norm_rate cwnr ON cwnr.id = iwn.contract_working_norm_rate_id 
  INNER JOIN additional_service a1 ON a1.id = cwnr.service_id
  INNER JOIN report_code rc1 ON rc1.id = a1.report_code_id 
  INNER JOIN invoicing i ON i.id = iwn.invoicing_id 
  INNER JOIN cargo_zone cz1 ON cz1.id = i.cargo_zone_id
  LEFT JOIN invoice_type it ON it.id = i.invoice_type_id 
  INNER JOIN contract_cargo_head cch1 ON cch1.id = i.contract_cargo_head_id
  INNER JOIN contract c1 ON c1.id = cch1.contract_id 
  INNER JOIN cargo_nomenclature cn ON cn.id = cch1.cargo_id
  WHERE UPPER(it.invoice_type_name) IN ('ИМПОРТ', 'ЭКСПОРТ', 'КАБОТАЖ')
  AND i.cooperated = p_cooperated
  AND c1.cargo_status = p_cargo_status
  AND cn.cargo_group_id = p_cargo_group_id
  AND i.cargo_zone_id = p_cargo_zone_id 
  AND cz1.cargo_zone_number = p_cargo_zone_number
  AND i.invoicing_date BETWEEN p_invoicing_date_from AND p_invoicing_date_to
  AND UPPER(rc1.report_code_name) = p_report_code_name), 0) 
  + 
  IFNULL((SELECT COALESCE(SUM(e.sum_rub), 0) 
  FROM invoicing_additional_service_editing e 
  INNER JOIN additional_service a ON a.id = e.service_id 
  INNER JOIN report_code rc ON rc.id = a.report_code_id
  INNER JOIN invoicing i ON i.id = e.invoicing_id 
  INNER JOIN cargo_zone cz1 ON cz1.id = i.cargo_zone_id 
  LEFT JOIN invoice_type it ON it.id = i.invoice_type_id
  INNER JOIN contract_cargo_head cch1 ON cch1.id = i.contract_cargo_head_id 
  INNER JOIN contract c1 ON c1.id = cch1.contract_id 
  INNER JOIN cargo_nomenclature cn ON cn.id = cch1.cargo_id
  WHERE e.show_in_report = 'Y' 
  AND UPPER(it.invoice_type_name) IN ('ИМПОРТ', 'ЭКСПОРТ', 'КАБОТАЖ')
  AND i.cooperated = p_cooperated 
  AND c1.cargo_status = p_cargo_status
  AND cn.cargo_group_id = p_cargo_group_id
  AND i.cargo_zone_id = p_cargo_zone_id
  AND cz1.cargo_zone_number = p_cargo_zone_number
  AND i.invoicing_date BETWEEN p_invoicing_date_from AND p_invoicing_date_to
  AND UPPER(rc.report_code_name) = p_report_code_name), 0) 
  , 2) INTO val;

  RETURN val;
END;



Вызов функции в качестве скалярного подзапроса:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT
  profit_coop_yn(pcp.cargo_status, cg.id, cz.id, '1', :date_from, :date_to, 'ПЕРЕГРУЗКА', 'N') AS sum_fact_prr_1,
  profit_coop_yn(pcp.cargo_status, cg.id, cz.id, '1', :date_from, :date_to, 'ТЭО', 'N') AS sum_fact_teo_1,
  profit_coop_yn(pcp.cargo_status, cg.id, cz.id, '1', :date_from, :date_to, 'ПРОЧИЕ', 'N') AS sum_fact_other_1

  FROM plan_cargo_processing pcp
  INNER JOIN cargo_group cg ON cg.id = pcp.cargo_group_id
  INNER JOIN cargo_zone cz ON cz.id = pcp.cargo_zone_id
  WHERE pcp.cooperated = 'N'
  AND pcp.year = :year 
  AND pcp.month = :month
...
Рейтинг: 0 / 0
Ошибка - слишком длинная процедура
    #39539298
svnvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо, все красиво получилось!
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
CREATE DEFINER = 'cargoport'@'%' PROCEDURE `profit_export_zones`(
        IN `p_year` INTEGER(11),
        IN `p_month_begin` INTEGER(11),
        IN `p_month_end` INTEGER(11),
        IN `p_date_from` DATETIME,
        IN `p_date_to` DATETIME,
        IN `p_div` INTEGER(11),
        IN `p_decimal_places` INTEGER(11)
    )
    NOT DETERMINISTIC
    READS SQL DATA
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
  SELECT *, 
  sum_fact_prr_1 + sum_fact_other_1 + sum_fact_teo_1 + sum_fact_fares_1 + sum_fact_storage_1 AS sum_fact_1,
  sum_fact_prr_2 + sum_fact_other_2 + sum_fact_teo_2 + sum_fact_fares_2 + sum_fact_storage_2 AS sum_fact_2,
  sum_fact_prr_4 + sum_fact_other_4 + sum_fact_teo_4 + sum_fact_fares_4 + sum_fact_storage_4 AS sum_fact_4,
  sum_fact_prr + sum_fact_other + sum_fact_teo + sum_fact_fares + sum_fact_storage AS sum_fact
  
  FROM

  (SELECT cg.cargo_group_name, 
  
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '1', p_date_from, p_date_to, 'ПЕРЕГРУЗКА')/p_div, p_decimal_places) AS sum_fact_prr_1,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '1', p_date_from, p_date_to, 'ПРОЧИЕ')/p_div, p_decimal_places) AS sum_fact_other_1,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '1', p_date_from, p_date_to, 'ТЭО')/p_div, p_decimal_places) AS sum_fact_teo_1,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '1', p_date_from, p_date_to, 'ПРОВОЗНАЯ ПЛАТА')/p_div, p_decimal_places) AS sum_fact_fares_1,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '1', p_date_from, p_date_to, 'ХРАНЕНИЕ')/p_div, p_decimal_places) AS sum_fact_storage_1,
  
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '2', p_date_from, p_date_to, 'ПЕРЕГРУЗКА')/p_div, p_decimal_places) AS sum_fact_prr_2,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '2', p_date_from, p_date_to, 'ПРОЧИЕ')/p_div, p_decimal_places) AS sum_fact_other_2,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '2', p_date_from, p_date_to, 'ТЭО')/p_div, p_decimal_places) AS sum_fact_teo_2,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '2', p_date_from, p_date_to, 'ПРОВОЗНАЯ ПЛАТА')/p_div, p_decimal_places) AS sum_fact_fares_2,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '2', p_date_from, p_date_to, 'ХРАНЕНИЕ')/p_div, p_decimal_places) AS sum_fact_storage_2,
  
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '4', p_date_from, p_date_to, 'ПЕРЕГРУЗКА')/p_div, p_decimal_places) AS sum_fact_prr_4,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '4', p_date_from, p_date_to, 'ПРОЧИЕ')/p_div, p_decimal_places) AS sum_fact_other_4,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '4', p_date_from, p_date_to, 'ТЭО')/p_div, p_decimal_places) AS sum_fact_teo_4,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '4', p_date_from, p_date_to, 'ПРОВОЗНАЯ ПЛАТА')/p_div, p_decimal_places) AS sum_fact_fares_4,
  ROUND(invoicing_sum_zonenum(pcp.cargo_status, cg.id, cz.id, '4', p_date_from, p_date_to, 'ХРАНЕНИЕ')/p_div, p_decimal_places) AS sum_fact_storage_4,
  
  ROUND(invoicing_sum(pcp.cargo_status, cg.id, cz.id, p_date_from, p_date_to, 'ПЕРЕГРУЗКА')/p_div, p_decimal_places) AS sum_fact_prr,
  ROUND(invoicing_sum(pcp.cargo_status, cg.id, cz.id, p_date_from, p_date_to, 'ПРОЧИЕ')/p_div, p_decimal_places) AS sum_fact_other,
  ROUND(invoicing_sum(pcp.cargo_status, cg.id, cz.id, p_date_from, p_date_to, 'ТЭО')/p_div, p_decimal_places) AS sum_fact_teo,
  ROUND(invoicing_sum(pcp.cargo_status, cg.id, cz.id, p_date_from, p_date_to, 'ПРОВОЗНАЯ ПЛАТА')/p_div, p_decimal_places) AS sum_fact_fares,
  ROUND(invoicing_sum(pcp.cargo_status, cg.id, cz.id, p_date_from, p_date_to, 'ХРАНЕНИЕ')/p_div, p_decimal_places) AS sum_fact_storage

  FROM plan_cargo_processing pcp
  INNER JOIN cargo_group cg ON cg.id = pcp.cargo_group_id
  INNER JOIN cargo_zone cz ON cz.id = pcp.cargo_zone_id
  WHERE pcp.cargo_status = 'export'
  AND pcp.year = p_year
  AND pcp.month BETWEEN p_month_begin AND p_month_end
  
  GROUP BY cg.id) iq
  ORDER BY cargo_group_name
  ;
END;
...
Рейтинг: 0 / 0
Ошибка - слишком длинная процедура
    #39539775
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svnvlad,

главное, че-то никто не посоветовал убрать НЕОБЯЗАТЕЛЬНОЕ слово INNER. Вместе с пробелом 6 байт неоднократно бы сэкономилось.

p.s. слова INNER и OUTER - необязательные. Прошу это запомнить.
...
Рейтинг: 0 / 0
8 сообщений из 58, страница 3 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Ошибка - слишком длинная процедура
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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