powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Обращение к внешней таблице в цикле
12 сообщений из 12, страница 1 из 1
Обращение к внешней таблице в цикле
    #39346980
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет.

Пишу импорт данных из MS SQL в PostgreSQL через TDS FDW (версия FDW - 2.0.0). Версия PostgreSQL - 9.4 , OS - freebsd.
Суть проблемы : в цикле FOR IN LOOP .. END LOOP вызывается некая функция PL/pgSQL, в которой есть SELECT к внешней таблице.
Результат работы цикла - сотни строк, поэтому функция должна быть вызвана столько же раз. На 6 -ой итерации - в момент выполнения запроса к внешней таблице - происходит какая-то необъяснимая подстановка/замещение значение переменной на NULL в условии блока where запроса к внешней таблице. Кто - нибудь сталкивался с подобным?

Текст основной функции, где происходит вызов :
Код: plsql
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.
CREATE OR REPLACE FUNCTION public.*****(pnseason_id integer, pntournament_id integer)
 RETURNS void
 LANGUAGE plpgsql
 SECURITY DEFINER
AS $function$
DECLARE
  CUR RECORD;

BEGIN

  FOR CUR IN
    SELECT t.*,
           fm.id     id_c
      FROM (
            SELECT *
              FROM dbs_calendar  where season_id = pnSEASON_ID and tournament_id = pnTOURNAMENT_ID
           )   t
           LEFT JOIN ****** on (t.ID =  fm.ID)
     WHERE t.ts <> coalesce(fm.TS,('01.01.1990' :: TIMESTAMP(3)))
  LOOP

      PERFORM dbs_match_process(CUR.ID);
   
  END LOOP;

END;$function$
 



Текст вызываемой функции в цикле :

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
CREATE OR REPLACE FUNCTION public.dbs_match_process(pnmatch_id integer)
 RETURNS void
 LANGUAGE plpgsql
 STRICT SECURITY DEFINER
AS $function$
DECLARE
  rCALENDAR   dbs_calendar%ROWTYPE;
  

BEGIN
  RAISE NOTICE 'match = %',pnmatch_id;
  
  BEGIN
    SELECT t.*
      INTO STRICT
           rCALENDAR
      FROM dbs_calendar t
     WHERE t.ID = pnmatch_id;
  EXCEPTION  WHEN NO_DATA_FOUND THEN
    RAISE EXCEPTION 'DBS матч не найден с ID --> %', pnMATCH_ID;
  END;
END;$function$



Передаваемые ID - все не null (так как являются PK). Именно на 6 ой итерации происходит неявная подстановка pnmatch_id на null в запросе
Код: sql
1.
2.
3.
4.
5.
SELECT t.*
      INTO STRICT
           rCALENDAR
      FROM dbs_calendar t
     WHERE t.ID = pnmatch_id;




Заранее, спасибо.
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39346994
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cristiano_Rivaldo,

авторSELECT t.*,
fm.id id_c
авторLEFT JOIN ****** on (t.ID = fm.ID)
авторPERFORM dbs_match_process(CUR.ID);
Которое из двух полей id будет доступно в строке под псевдонимом id?
Видимо, второе. Пока left join строки находил, это не имело значения, как не нашёл - подставил NULL. Используйте алиасы.
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39346995
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ой, мне запятая почудилась после fm.id. А сообщение грохнуть нельзя...
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39347008
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Именно на 6 итерации. Неважно какие параметры указаны в (pnseason_id integer, pntournament_id integer).
Скрин запроса на стороне MS SQL прилагается.
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39347024
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для начала попробуйте вот так вот (и посмотрите что в raise warning идет, null или нормальное значение).
Если идет не null а в FDW приезжает null - похоже на глюк в FDW
Если все работает как надо - то аккуратнее с запросами и алиасами (и вообще с использованием * нотации в запросах не по делу).

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
CREATE OR REPLACE FUNCTION public.*****(pnseason_id integer, pntournament_id integer)
 RETURNS void
 LANGUAGE plpgsql
 SECURITY DEFINER
AS $function$
DECLARE
  t_id integer;
BEGIN

  FOR t_id IN
    SELECT t.id
      FROM (
            SELECT *
              FROM dbs_calendar  where season_id = pnSEASON_ID and tournament_id = pnTOURNAMENT_ID
           )   t
           LEFT JOIN ****** on (t.ID =  fm.ID)
     WHERE t.ts <> coalesce(fm.TS,('01.01.1990' :: TIMESTAMP(3)))
  LOOP
      RAISE WARNING 'match = %', t_id;
      PERFORM dbs_match_process(t_id);
  END LOOP;

END;$function$




--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39347045
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,

Не помогло...
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39347072
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cristiano_Rivaldo,

А зачем вы альфа версию TDW используете?
Попробуйте стабильную 1.0.8

--
Maxim Boguk
www.postgresql-consulting.ru
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39347257
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,

Потому что именно в ней реализован поиск записей по индексу. Т.е. при обращении закачивается не вся таблица, а только те записи, которые указаны в блоке where.
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39347313
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Причем такая же ошибка выходит даже если написать через with :

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
with t (id) AS
(
  SELECT t.id
      FROM (
            SELECT *
              FROM dbs_calendar where season_id = 16 and tournament_id = 1
           )   t
           LEFT JOIN f_match fm  on (t.ID =  fm.ID)
     WHERE t.ts <> coalesce(fm.TS,('01.01.1990' :: TIMESTAMP(3)))
)

SELECT dbs_match_process(t.id)
   FROM t



И почему именно на 6 - ой итерации ? Что за магическое число 6 ?
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39347767
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cristiano_RivaldoПричем такая же ошибка выходит даже если написать через with :

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
with t (id) AS
(
  SELECT t.id
      FROM (
            SELECT *
              FROM dbs_calendar where season_id = 16 and tournament_id = 1
           )   t
           LEFT JOIN f_match fm  on (t.ID =  fm.ID)
     WHERE t.ts <> coalesce(fm.TS,('01.01.1990' :: TIMESTAMP(3)))
)

SELECT dbs_match_process(t.id)
   FROM t



И почему именно на 6 - ой итерации ? Что за магическое число 6 ?

Есть у меня теория почему именно на 6той... а попробуйте переделать public.dbs_match_process как
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
CREATE OR REPLACE FUNCTION public.dbs_match_process(pnmatch_id integer)
 RETURNS void
 LANGUAGE plpgsql
 STRICT SECURITY DEFINER
AS $function$
DECLARE
  rCALENDAR   dbs_calendar%ROWTYPE;
  

BEGIN
  RAISE NOTICE 'match = %',pnmatch_id;
  
  BEGIN
   EXECUTE 'SELECT t.* FROM dbs_calendar t WHERE t.ID = $1' INTO STRICT rCALENDAR USING pnmatch_id;
  EXCEPTION  WHEN NO_DATA_FOUND THEN
    RAISE EXCEPTION 'DBS матч не найден с ID --> %', pnMATCH_ID;
  END;
END;$function$
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39349220
Cristiano_Rivaldo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,

Не помогло. Заметил что если даже обрабатывать порциями по 5 и делать все в одной сессии - то на втором запуске тоже вылетает ошибка. Как буд-то это ограничение на всю сессию... Но если открыть новое окно sql запросов (новая сессия) - то все норм.
...
Рейтинг: 0 / 0
Обращение к внешней таблице в цикле
    #39349551
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cristiano_RivaldoMaxim Boguk,

Не помогло. Заметил что если даже обрабатывать порциями по 5 и делать все в одной сессии - то на втором запуске тоже вылетает ошибка. Как буд-то это ограничение на всю сессию... Но если открыть новое окно sql запросов (новая сессия) - то все норм.

Очевидная бага в FDW. Напишите автору.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Обращение к внешней таблице в цикле
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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