Различные результаты функции postgreSQL между JDBC и консолью - PullRequest
0 голосов
/ 14 октября 2019

У меня есть функция в plpgsql, которая, когда я запускаю ее с одним и тем же пользователем на одной и той же таблице в одной и той же базе данных, я получаю разные результаты между вызовом JDBC и psql или psycopg2.

SELECT id,name,
       date_deadline,
       g2j(date_deadline) AS converted_date 
FROM project_task 
WHERE NOT date_deadline ISNULL ;

приводит к psycopg2 и psql:

 id |               name               | date_deadline | converted_date 
----+----------------------------------+---------------+----------------
 21 | Document management              | 2019-10-29    | 1398-08-06
 26 | Create new components            | 2019-09-21    | 1398-06-29
 11 | You can set a deadline on a task | 2019-11-13    | 1398-08-21
 23 | User interface improvements      | 2020-04-08    | 1399-01-19
 24 | Planning and budget              | 2019-10-19    | 1398-07-26
 17 | Room 1: Decoration               | 2019-10-14    | 1398-07-21
 16 | Black Chairs for managers        | 2019-10-19    | 1398-07-26
 15 | Noise Reduction                  | 2019-10-24    | 1398-08-01
 31 | Unit Testing                     | 2019-02-16    | 1397-11-26
(9 rows)

Результаты JDBC в консоли pyCharm postgres:

21  Document management 2019-10-29  1398-08-07
26  Create new components   2019-09-21  1398-06-30
11  You can set a deadline on a task    2019-11-13  1398-08-22
23  User interface improvements 2020-04-08  1399-01-20
24  Planning and budget 2019-10-19  1398-07-27
17  Room 1: Decoration  2019-10-14  1398-07-22
16  Black Chairs for managers   2019-10-19  1398-07-27
15  Noise Reduction 2019-10-24  1398-08-02
31  Unit Testing    2019-02-16  1397-11-27

Второй результат (JDBC) правильный.

           Column           |            Type             | Collation | Nullable |                 Default                  
----------------------------+-----------------------------+-----------+----------+------------------------------------------
 id                         | integer                     |           | not null | nextval('project_task_id_seq'::regclass)
 name                       | character varying           |           | not null | 
 date_deadline              | date                        |           |          | 

Почему я получаю это? & - |

Я использую PostgreSQL 10.9 в Ubuntu

psql версия также 10,9

Функция

- Функция: g2j (отметка времени счасовой пояс)

- ФУНКЦИЯ КАПЛИ g2j (отметка времени с часовым поясом);

CREATE OR REPLACE FUNCTION g2j(in_date timestamp with time zone)
  RETURNS character varying AS
$BODY$
DECLARE
y smallint;
aday smallint;
amonth smallint;
ayear smallint;
value smallint;
a1 char(4);
b1 char(2);
c1 char(2);
Tday smallint;
Tmonth smallint;
Tyear smallint;
temp smallint;
CabisehYear smallint;
TMonthEnd smallint;
numdays int;
now_day timestamp without time zone;
a timestamp without time zone;
Const_Date timestamp without time zone;
BEGIN
set datestyle to MDY;
Const_Date = cast('3/21/1921' as timestamp without time zone);
--if(length(cast(in_date as text))< 14 )then
--  in_date=in_date+time '01:30';
 --return in_date;
--end if;

numdays = DATE_PART('day',in_date - Const_Date);
aday = 1;
amonth = 1;
ayear = 1300;
CabisehYear =cast((numdays / 1461) as int);
numdays = numdays - CabisehYear * 1461;
Tyear = cast((numdays / 365) as int);
If Tyear = 4 then
Tyear = Tyear - 1;
end if;
numdays = numdays - Tyear * 365;
Tmonth =cast((numdays / 31) as int);
If (Tmonth > 6) then
Tmonth = 6;
end if;
numdays = numdays - Tmonth * 31;
TMonthEnd = 0;
If (numdays >= 30 And Tmonth = 6 ) then
TMonthEnd =cast((numdays / 30) as int);
If TMonthEnd >= 5 then
TMonthEnd = 5;
end if;
numdays = numdays - TMonthEnd * 30;
End if;
Tmonth = (TMonthEnd + Tmonth);
Tday = numdays;
Tyear = (Tyear + CabisehYear * 4);
ayear = (ayear + Tyear);
amonth = amonth + Tmonth;
aday = aday + Tday;

a1 = ayear;
b1 = amonth;
c1 = aday;


If length(b1) = 1 then
b1 = '0' || b1;
end if;
If length(c1) = 1 then
c1 = '0' || c1;
end if;
return a1 || '-' || b1 || '-' || c1;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

1 Ответ

0 голосов
/ 15 октября 2019

Поскольку входным параметром функции является timestamp with time zone, преобразование значений, которые не имеют информации о часовом поясе (например, поля date), включает добавление местного часового пояса. Согласно документам :

Параметр конфигурации TimeZone можно установить в файле postgresql.conf или любым другим стандартным способом, описанным в главе19. Есть также несколько специальных способов установить его:

  • Команда SQL SET TIME ZONE устанавливает часовой пояс для сеанса. Это альтернативное написание SET TIMEZONE TO с более совместимым с SQL-spec синтаксисом.
  • Переменная окружения PGTZ используется клиентами libpq для отправки команды SET TIME ZONE на сервер при подключении.

Это означает, что клиенты, использующие разные библиотеки / драйверы / параметры среды, могут иметь разные мнения о том, что такое местный часовой пояс, что, в свою очередь, может повлиять на результаты запроса.

Каквычисления в этой функции, по-видимому, предназначены для обработки дат и вообще не зависят от часового пояса; его следует изменить, чтобы он принимал параметр date или timestamp without time zone.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...