powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Вставить данные в таблицу из JSON объекта
25 сообщений из 42, страница 1 из 2
Вставить данные в таблицу из JSON объекта
    #38308749
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеем переменную типа JSON
В ней находятся данные, которые необходимо вставить в таблицу.
Можно, конечно вручную выбирать поля в определенном порядке и формировать строку для выполнения вставки данных, но надеюсь, что есть более простой способ.

Помогите пожалуйста кто знает как.
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308751
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хотелось бы функцию типа json_to_row...
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308805
Фотография Misha Tyurin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sp,

http://www.postgresql.org/docs/9.2/static/functions-json.html - 92

но
http://www.postgresql.org/docs/9.3/static/functions-json.html - 93 уже есть! щас будет скоро совсем

json_populate_record
json_populate_recordset


ну и щас hstore http://www.postgresql.org/docs/9.2/static/hstore.html - 92

populate_record
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308837
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Misha Tyurin,

спасибо за информацию, попробовал, но нифига не получается: json_populate_record для ключевого поля возвращает null (естественно когда вставляем новую запись) и при попытке вставить данные получаю ошибку

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
DECLARE
  r matable1;
  opt pg_catalog.json;
  text_var1 text;
  text_var2 text;
  text_var3 text;
BEGIN
    opt := '{...........}'; --тут вставляем реальный объект JSON
    select * from json_populate_record(null::matable1, opt) into r;
    insert into matable1 VALUES(r);
    ......
    EXCEPTION WHEN OTHERS THEN 
    GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,
                          text_var2 = PG_EXCEPTION_DETAIL,
                          text_var3 = PG_EXCEPTION_HINT;
    RAISE NOTICE '%', text_var1;
END



Получаем ошибку при выполнении:
Код: plaintext
1.
ERROR:  control reached end of function without RETURN
NOTICE:  column "id" is of type integer but expression is of type mytable1

id в данной таблице - serial;

попытка перечислить поля таблицы в конструкции Insert into (c id и без него)
приводит к ошибке "INSERT has more target columns than expressions"
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308845
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот полный пример

Код: 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.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
CREATE TABLE core.test (
  id SERIAL,
  name VARCHAR(50) NOT NULL,
  system BOOLEAN DEFAULT false NOT NULL,
  created_on TIMESTAMP(0) WITH TIME ZONE DEFAULT clock_timestamp() NOT NULL,
  CONSTRAINT test_pkey PRIMARY KEY(id)
) 
WITH (oids = false);


CREATE OR REPLACE FUNCTION core.test (
)
RETURNS pg_catalog.json AS
$body$
DECLARE
opt pg_catalog.json = '{' ||
   '"name": "Вася"' ||
  '}';
  r core.test;
  text_var1 text;
  text_var2 text;
  text_var3 text;
  
  begin
  	select * from json_populate_record(null::core.test, opt) into r;
--        return row_to_json(r);
    insert into core.test (id, name, system, created_on)
		 VALUES(r);
    return row_to_json(r);
    EXCEPTION WHEN OTHERS THEN 
    GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,
                          text_var2 = PG_EXCEPTION_DETAIL,
                          text_var3 = PG_EXCEPTION_HINT;
    RAISE NOTICE '%', text_var1;
  end
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308862
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
разобрался - вставку нужно делать так

Код: plsql
1.
insert into core.test VALUES(r.*);



но перед вставкой необходимо id присвоить правильное значения ключа id и заполнить также все поля имеющие значения по-умолчанию!!!
тут как-то не очень удобно! Получается много геммороя - надо выяснить какие поля ключевые и имеющие значения по-умолчанию и если они в переменной JSON раны null то их надо заполнить значениями, а для этого их надо узнать.
В PG, к сожалению, не проходит даже такой оператор, который в других базах работает на ура

Код: plsql
1.
insert into core.test VALUES('Петя')



надо обязательно записать так

Код: plsql
1.
insert into core.test VALUES(DEFAULT, 'Петя')



грустно..
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308864
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
грустно и от того что в других БД если поле имеет значение по-умолчанию и при вставке оно равно null - БД его заполняет самостоятельно, а в PG надо либо узнать значения поля по-умолчанию, либо сформировать строку оператора insert into и вместо ключей и полей по-молчанию вставить константу DEFAULT - однако и то и другое - геморрой!((
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308879
ну вы просто null не передавайте. как встретите в hstore null - так и выкалывайте -
а то я за вас рад -как же null вставлять в поле, если там какая-то сволочь дефолт прописала, но поле всё ж таки нуллабл, и мы именно null и хотим вставить
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308880
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
default but nullable,

дык json_populate_record(null::core.test, opt) сам вставляет отсутствующие поля и заполняет их NULL!
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308937
spdefault but nullable,

дык json_populate_record(null::core.test, opt) сам вставляет отсутствующие поля и заполняет их NULL!ру какбе врать-врите, но не заговаривайтесь
вот это вот
Код: plsql
1.
null::core.test

- пупкин написал ?
рассказать вам, что вы делаете этим оператором ?
или сами догадаетесь
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308958
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пупкин написалрассказать вам, что вы делаете этим оператором ?
или сами догадаетесь

расскажите, будьте любезны - интересно узнать
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308960
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для информации

Код: plsql
1.
2.
3.
4.
5.
6.
opt pg_catalog.json = '{' ||
   '"name": "Вася"' ||
  '}';
.......
select * from json_populate_record(null::core.test, opt) into r;
return row_to_json(r);



выводит
Код: javascript
1.
{"id":null,"name":"Вася","system":null,"created_on":null}
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308961
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
для информации

Код: plsql
1.
2.
3.
4.
5.
6.
7.
opt pg_catalog.json = '{' ||
   '"name": "Вася"' ||
  '}';
r core.test;
.......
select * from json_populate_record(r, opt) into r;
return row_to_json(r);



выводит
Код: javascript
1.
{"id":null,"name":"Вася","system":null,"created_on":null}
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38308968
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
из документации

json_populate_record(base anyelement, from_json json, [, use_json_as_text bool=false]

Expands the object in from_json to a row whose columns match the record type defined by base. Conversion will be best effort; columns in base with no corresponding key in from_json will be left null. A column may only be specified once.
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309012
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spпупкин написалрассказать вам, что вы делаете этим оператором ?
или сами догадаетесь

расскажите, будьте любезны - интересно узнатьну вы блин даёте

делаем
Код: plsql
1.
SELEСT null::core.test


и смотрим
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309014
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗЫ

если не всё ещё понятно, делаем
Код: plsql
1.
SELEСT (null::core.test).*;


и медитируем на результат
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309025
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqЗЫ

если не всё ещё понятно, делаем
Код: plsql
1.
SELEСT (null::core.test).*;


и медитируем на результат

медитировал долго над обеими случаями, но...

ERROR: syntax error at or near "SELEСT"
LINE 1: SELEСT (null::core.test).*;
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309061
sp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
может будем разговаривать как специалисты, а не как работники околоакультных наук?
скажите что вы имеете сказать
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309074
Гость_0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
sp, null в поля записи пишите Вы сами, а не json_populate_record
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309206
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
spможет будем разговаривать как специалисты, а не как работники околоакультных наук?
скажите что вы имеете сказатьоколо - это ваше кредо

вы даже простой селект выполнить не можете, что наводит.

далее рассказываю, что происходит в
Код: plsql
1.
null::core.test


-- null кастится в тип core.test, т.е. создается объект (резултьтат выражения) типа core.test, все поля которого инициированы именно null - потому что вы сами об этом попросили.

(ну а далее популейт занимается тем, что заменяет в этом созданном вами рекорде, те поля, чьи кеи он обнаруживает в hstore на те значения, которые он в hstore находит)

-- т.е., как видите, никакой магии, и чтобы обнаружить отсутствие магии - совсем невредно было некоторое время помедитировать, а не надрачивать на непонятную формулу ~~ популейт(что-то-там) как на неведомое, но непременно магическое синтаксическое чЮдо.
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309227
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sp ERROR: syntax error at or near "SELEСT"
LINE 1: SELEСT (null::core.test).*;это у меня при полуслепом наборе translate англиница->руссица в SELECT отработал, что очевидно просто по подсветке синтаксиса
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309278
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sp, если не боитесь то можно типа такого попробовать :)
Код: 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.
create or replace function poly_def(tbl anyelement, h hstore) returns anyelement language plpgsql
as $$
declare
  r record;
  def text;
  tmp hstore default h;
  rec record;
begin
  for r in select * from
    each(hstore(populate_record(tbl, h))) src
    join pg_attribute a on a.attrelid = pg_typeof(tbl)::name::regclass::oid
                           and a.attname = src.key and src.value is null
    join pg_attrdef d on a.attrelid = d.adrelid and a.attnum = d.adnum
  loop
    execute 'select ' || r.adsrc || ' as res' into def;
    raise notice '%: % | % | %', r.key, r.value, r.adsrc, def;
    tmp := tmp || hstore(r.key, def);
  end loop;
  raise notice 'tmp: %', tmp;
  rec := populate_record(tbl, tmp);
  return rec;
end
$$;

select * from poly_def(null::core.test, 'name => jone');
NOTICE:  id: <NULL> | nextval('core.test_id_seq'::regclass) | 1
NOTICE:  system: <NULL> | false | f
NOTICE:  created_on: <NULL> | clock_timestamp() | 2013-06-25 12:09:54.788903+04
NOTICE:  tmp: "id"=>"1", "name"=>"jone", "system"=>"f", "created_on"=>"2013-06-25 12:09:54.788903+04"
 id | name | system |       created_on       
----+------+--------+------------------------
  1 | jone | f      | 2013-06-25 12:09:55+04
(1 строка)

Время: 16,934 мс
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309368
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёшsp, если не боитесь то можно типа такого попробовать :)
Код: sql
1.
2.
3.
4.
5.
6.
7.
create or replace function poly_def(tbl anyelement, h hstore) returns anyelement language plpgsql
as $$
---
    join pg_attribute a on a.attrelid = pg_typeof(tbl)::name::regclass::oid
                           and a.attname = src.key and src.value is null
    join pg_attrdef d on a.attrelid = d.adrelid and a.attnum = d.adnum
---



ну если ажсторе аж установлено - можно не лазать по систейблам, и слегка забыть как они устроены.
а прямо
Код: plsql
1.
2.
3.
4.
5.
BEGIN;
CREATE table test (id serial ,field text);
SELECT akeys(hstore(null::test));
-- + медитировать на рез-т
-- 

для FOREACH fld IN ARRAY akeys(hstore(null::test)) уже достаточно, нет ?


кстати интересно, много такое поюзание ажсторе запросам к системным проиграет?
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309380
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
qwwqну если ажсторе аж установлено - можно не лазать по систейблама как значения по умолчанию получить?
...
Рейтинг: 0 / 0
Вставить данные в таблицу из JSON объекта
    #38309389
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёшqwwqну если ажсторе аж установлено - можно не лазать по систейблама как значения по умолчанию получить?а зачем ?
пусть лошадь думает - ку неё голова большая тьфу пусть трактор пашет - он железный
т.е пусть сам пж и получает - ему динамически INSERT надо правильно пошить
а не values
мне как-то вот так кажется
...
Рейтинг: 0 / 0
25 сообщений из 42, страница 1 из 2
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Вставить данные в таблицу из JSON объекта
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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