Postgresql

向表中插入由 JSON 表示的行

  • January 19, 2018

我一直在努力嘗試創建一個可以數據 JSONB(或 JSON,並不重要)的過程,一個表,並將 JSON 轉換為記錄並將該記錄插入表中。這是(大約)我最接近功能原型的:

CREATE OR REPLACE FUNCTION fn_alter_entity(data JSONB, table_type anyelement) RETURNS VOID
   SECURITY INVOKER
   LANGUAGE plpgsql
AS $$
   DECLARE
       record RECORD;
       record_type RECORD;
   BEGIN
       EXECUTE format('SELECT x.* FROM (SELECT a.* FROM CAST(NULL as %s) a) x', pg_typeof(table_type))
           INTO record_type;
       record := jsonb_populate_record(record_type, data);
       INSERT INTO users SELECT (record).* RETURNING id;
   END;
$$;

因此,假設我執行以下操作:

SELECT fn_alter_entity('{"a": "b"}'::JSONB, users);

我收到以下錯誤:

ERROR: record type has not been registered
SQL state: 42809
Context: SQL statement "INSERT INTO users SELECT (record).* RETURNING id"
PL/pgSQL function fn_alter_entity(jsonb,anyelement) line 9 at SQL statement

現在,顯然我收到該錯誤的原因是它record_type實際上不是真正的記錄類型。現在,通常我們只會做類似jsonb_populate_record(data, NULL::users)jsonb_populate_record(data, NULL::events)類似的事情。但是如果我希望該記錄類型是動態的呢?有沒有可能?我覺得我快要解決這個問題了,但就是無法克服困難。我想做的就是能夠將 JSON 轉換為記錄。

我想你想要這樣的東西。

CREATE OR REPLACE FUNCTION fn_alter_entity(data JSONB, t TEXT )
 RETURNS VOID
 SECURITY INVOKER
AS $$
   BEGIN
       EXECUTE FORMAT(
         'INSERT INTO %I SELECT * FROM jsonb_populate_record( null::%I, $1);',
         t,
         t
       )
       USING data;
   END;
$$
LANGUAGE plpgsql
VOLATILE;

CREATE TABLE foo ( a int );
CREATE TABLE bar ( a int, b text );

SELECT fn_alter_entity( '{"a": 5}', 'foo' );
SELECT fn_alter_entity( '{"a": 42}', 'foo' );
SELECT fn_alter_entity( '{"a": 5, "b": "foo"}', 'bar' );
SELECT fn_alter_entity( '{"a": 42, "b": "baz"}', 'bar' );

test=# TABLE foo;
a  
----
 5
42
(2 rows)

test=# TABLE bar;
a  |  b  
----+-----
 5 | foo
42 | baz
(2 rows)

但是看看你可能要去哪裡,我強烈建議你看看PostgREST

引用自:https://dba.stackexchange.com/questions/177328