Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Обращение к внешней таблице в цикле / 12 сообщений из 12, страница 1 из 1
14.11.2016, 16:28
    #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
14.11.2016, 16:45
    #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
14.11.2016, 16:47
    #39346995
Melkij
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к внешней таблице в цикле
ой, мне запятая почудилась после fm.id. А сообщение грохнуть нельзя...
...
Рейтинг: 0 / 0
14.11.2016, 16:58
    #39347008
Cristiano_Rivaldo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к внешней таблице в цикле
Именно на 6 итерации. Неважно какие параметры указаны в (pnseason_id integer, pntournament_id integer).
Скрин запроса на стороне MS SQL прилагается.
...
Рейтинг: 0 / 0
14.11.2016, 17:28
    #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
14.11.2016, 17:54
    #39347045
Cristiano_Rivaldo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к внешней таблице в цикле
Maxim Boguk,

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

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

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

Потому что именно в ней реализован поиск записей по индексу. Т.е. при обращении закачивается не вся таблица, а только те записи, которые указаны в блоке where.
...
Рейтинг: 0 / 0
15.11.2016, 10:07
    #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
15.11.2016, 17:10
    #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
17.11.2016, 16:03
    #39349220
Cristiano_Rivaldo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обращение к внешней таблице в цикле
Maxim Boguk,

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

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

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


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