如何在将行插入PostgreSQL数据库时使用DEFAULT关键字

huangapple go评论88阅读模式
英文:

How to use DEFAULT when inserting rows into postgres sql database

问题

考虑到我在我的PostgreSQL数据库中有一个名为t1的表,如下所示:

CREATE TABLE t1 (
    id SERIAL PRIMARY KEY, 
    col_2 TEXT DEFAULT "foo", 
    col_3 TEXT NOT NULL DEFAULT "bar", 
    ...
    col_X INTEGER NOT NULL DEFAULT 42
);

并且我收到一个JSON对象obj,我将其解组为一个结构体ObjStrct

type ObjStrct {
    id *int32  `json:id,omitempty`, 
    s1 *string `json:s1,omitempty`, 
    s2 *string `json:s2,omitempty`, 
    ...
    nr *int32  `json:nr,omitempty`
}
var obj ObjStrct
err := json.NewDecoder(request.Body).Decode(&obj)
// 错误处理已完成

现在我想将该对象插入到我的数据库中:

// 连接到数据库已建立
row := db.QueryRow(
		`INSERT INTO 
            t1 (col_1, col_2, ..., col_X)
        VALUES
            ($1, $2, ..., $X)
        RETURNING 
            id;`, 
        *obj.s1, *obj.s2, ..., *obj.nr)

问题是:所有这些obj.*值都可以为nil,在这种情况下应该使用SQL的DEFAULT值。

我的问题是:我该如何实现这一点?

  • 来自sql包的数据类型(sql.Null)据我所知不支持DEFAULT关键字。

  • func defaultOnNil(v *int32) any { ... }这样的函数,当v为nil时返回"DEFAULT",而不是v,是不起作用的。请参阅此相关帖子

英文:

Consider that I have a table t1 in my postgres database like so:

CREATE TABLE t1 (
    id SERIAL PRIMARY KEY, 
    col_2 TEXT DEFAULT "foo", 
    col_3 TEXT NOT NULL DEFAULT "bar", 
    ...
    col_X INTEGER NOT NULL DEFAULT 42
);

And that I receive a JSON object obj which I unmarshall in a struct ObjStrct:

type ObjStrct {
    id *int32  `json:id,omitempty`, 
    s1 *string `json:s1,omitempty`, 
    s2 *string `json:s2,omitempty`, 
    ...
    nr *int32  `json:nr,omitempty`
}
var obj ObjStrct
err := json.NewDecoder(request.Body).Decode(&obj)
// error handling has been done

Now I want to insert that object into my database:

// connection to db established
row := db.QueryRow(
		`INSERT INTO 
            t1 (col_1, col_2, ..., col_X)
        VALUES
            ($1, $2, ..., $X)
        RETURNING 
            id;`, 
        *obj.s1, *obj.s2, ..., *obj.nr)

The issue is: All those obj.*-values could be nil in which case the sql DEFAULT value should be used.

My question is: How do I achieve this?

  • datatypes from the sql package (sql.Null<TYPE>) do not support the DEFAULT keyword afaik.

  • Functions like func defaultOnNil(v *int32) any { ... } returning "DEFAULT" when v is nil and v instead do not work. See this related post

答案1

得分: 2

使用列的DEFAULT值时,INSERT应该在插入时排除该列

这意味着你需要处理JSON对象,找出哪些值为nil,并从查询中删除它们。

例如,如果JSON对象的s2为nil,则应该从查询中删除col2;它应该修改为:

row := db.QueryRow(
        `INSERT INTO 
            t1 (col_1, ..., col_X) -- 这里删除了"col2"
        VALUES
            ($1, ..., $X)          -- 这里删除了"$2"
        RETURNING 
            id, col2;`,            -- 这里添加了"col2"
        *obj.s1, *obj.s2)

任何实现动态SQL功能的ORM都可以轻松完成这个操作。

英文:

To use the DEFAULT value of a column an INSERT should exclude the column while inserting.

This means, you'll need to process the JSON object, find out which values are nil, and remove them from the query.

For example, if the JSON object has s2 as nil, then col2 should be removed from your query; it should be modified as:

row := db.QueryRow(
        `INSERT INTO 
            t1 (col_1, ..., col_X) -- "col2" removed here
        VALUES
            ($1, ..., $X)          -- "$2" removed here
        RETURNING 
            id, col2;`,            -- "col2" added here
        *obj.s1, *obj.s2)

This is easily done by any ORM that implements Dynamic SQL functionality.

答案2

得分: 0

另一个选项是在json解析的值之前发送关键字DEFAULT。所以代码如下:

row := db.QueryRow(
        `INSERT INTO 
            t1 (col_1, col_2, ..., col_X)
        VALUES
            ($1, $2, ..., $X)
        RETURNING 
            id;`, 
        *obj.s1, DEFAULT, ..., *obj.nr); 

在这种用法中,不需要在DEFAULT周围使用引号,因为它是一个关键字。

英文:

Another option is send the keyword DEFAULT instead of the value parsed from the json. So:

row := db.QueryRow(
        `INSERT INTO 
            t1 (col_1, col_2, ..., col_X)
        VALUES
            ($1, $2, ..., $X)
        RETURNING 
            id;`, 
        *obj.s1, DEFAULT, ..., *obj.nr); 

You do not use quotes around DEFAULT, in this usage it is a keyword.

huangapple
  • 本文由 发表于 2023年6月16日 18:47:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76489434.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定