首先,請原諒我,如果我使用錯誤的條款,我非常新的PostgreSQL和NoSQL風格的數據存儲。繼續:在Postgres中插入帶有自動遞增字段的JSON列?
我正在使用npgsql將.NET項目連接到PostgreSQL數據庫。我們將它用作NoSQL文檔存儲,我們的表由id
列的主鍵和data
列中的jsonb對象組成,其他都沒有。
在data
列中,我們還想要一種生成每個插入時自動遞增的id字段的方法。這個ID不一定需要匹配主鍵,但這就是我正在工作的假設。
我已經能夠使用下面的腳本來使pgAdmin的這項工作:
drop table public.testjson;
drop sequence public.testjson_id_seq;
CREATE SEQUENCE public.testjson_id_seq
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
ALTER TABLE public.testjson_id_seq
OWNER TO login;
CREATE TABLE public.testjson
(
id bigint NOT NULL DEFAULT nextval('testjson_id_seq'::regclass),
data jsonb,
CONSTRAINT testjson_pkey PRIMARY KEY (id)
);
ALTER TABLE public.testjson
OWNER TO login;
-- Insert data using currval --
INSERT INTO testjson (data) VALUES(to_jsonb('{"jsonid": '||currval('testjson_id_seq'::regclass)::bigint||', moreStuff: "all the stuff!"}'));
INSERT INTO testjson (data) VALUES(to_jsonb('{"jsonid": '||currval('testjson_id_seq'::regclass)::bigint||', moreStuff: "all the stuff!"}'));
INSERT INTO testjson (data) VALUES(to_jsonb('{"jsonid": '||currval('testjson_id_seq'::regclass)::bigint||', moreStuff: "all the stuff!"}'));
INSERT INTO testjson (data) VALUES(to_jsonb('{"jsonid": '||currval('testjson_id_seq'::regclass)::bigint||', moreStuff: "all the stuff!"}'));
select * from testjson
-- Output --
id | data
---------------------------------------------------------
1 | "{\"jsonid\": 1, moreStuff: \"all the stuff!\"}"
2 | "{\"jsonid\": 2, moreStuff: \"all the stuff!\"}"
3 | "{\"jsonid\": 3, moreStuff: \"all the stuff!\"}"
4 | "{\"jsonid\": 4, moreStuff: \"all the stuff!\"}"
到目前爲止,一切都很好。我想我會重構這個,所以jsonid字段有自己的序列,並且使用nextval
而不是currval
(以防止導致重複的競爭條件),但問題不在於此。我在代碼方面無法複製這個問題。環顧其他questions這裏使我相信,這可能工作:
var crcmd = new NpgsqlCommand("INSERT INTO "+_schema+"."+table+" ("+JsonColumn+") VALUES (:json) RETURNING id;", _conn);
var jsonData = getSerializedJsonData(thing, primaryKey);
crcmd.Parameters.AddWithValue("json", NpgsqlDbType.Jsonb, jsonData);
returnId = (long) crcmd.ExecuteScalar();
...
private string getSerializedJsonData<T>(T thing, string primaryKey, string tableSeq)
{
var jsonThing = JsonConvert.SerializeObject(thing);
var bracketIndex = jsonThing.IndexOf('{');
var thingPrefix = jsonThing.Substring(0, bracketIndex + 1);
var thingData = jsonThing.Substring(bracketIndex + 1);
var pkEntry = "\"" + primaryKey +"\": currval('" + tableSeq + '::regclass)::bigint, ";
jsonThing = thingPrefix + pkEntry + thingData;
return jsonThing;
}
但是當我嘗試對其進行測試,以下異常被拋出:
Npgsql.PostgresException: 22P02: invalid input syntax for type json; Token "currval" is invalid
任何想法我錯了?
將數據插入直接作爲字符串打破了數據庫的基本規則查詢。你有沒有找到更好的解決方案? – piojo