CockroachDB 写数据报了这个错误,是因为postgres占位符是$n,不是?
参考文档:https://pkg.go.dev/github.com/lib/pq
package main
import (
"bytes"
"context"
"encoding/base64"
"encoding/binary"
"errors"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"strconv"
"strings"
"sync"
"syscall"
"time"
"github.com/jackc/pgx/v4"
"github.com/jmoiron/sqlx"
"github.com/sirupsen/logrus"
)
func main() {
db, err := sqlx.Connect("postgres", fmt.Sprintf("postgresql://root:admin@192.168.1.240:26257/wxrt?sslmode=disable"))
if err != nil {
logrus.WithError(err).Fatalln("connect db")
}
defer db.Close()
sequence, _ := NewSequence(1)
ValueStrings := []string{}
ValueArgs := make([]interface{}, 0, 7)
for j := 0; j < 1; j++ {
ValueStrings = append(ValueStrings, `($1,$2,$3,$4,$5,$6,$7)`)
ValueArgs = append(ValueArgs, sequence.Generate().Int64())
ValueArgs = append(ValueArgs, fmt.Sprint(`captured_image_uri`, sequence.Generate().Int64()))
ValueArgs = append(ValueArgs, fmt.Sprint(`captured_face_image_uri`, sequence.Generate().Int64()))
ValueArgs = append(ValueArgs, sequence.Generate().Int64())
ValueArgs = append(ValueArgs, sequence.Generate().Int64())
ValueArgs = append(ValueArgs, time.Now().Unix())
ValueArgs = append(ValueArgs, time.Now().Unix())
//fmt.Println("k=", k, "j=", j, "sequence.Generate().Int64()", sequence.Generate().Int64())
time.Sleep(1 * time.Microsecond)
}
dstmt := fmt.Sprintf(`INSERT INTO wxrt_device_record
(id,captured_image_uri,captured_face_image_uri,captured_image_id,captured_face_image_id,captured_at,created_at) VALUES %s `,
strings.Join(ValueStrings, `,`))
fmt.Println("dstmt", dstmt, "args", ValueArgs)
result, err := db.Exec(dstmt, ValueArgs...)
fmt.Printf("err:%+v", err)
if err != nil {
fmt.Errorf("创建失败:%s", err.Error())
}
fmt.Printf("result:%+v", result)
// Wait for interrupt signal to gracefully shutdown the server with
// a timeout of 5 seconds.
quit := make(chan os.Signal)
// kill (no param) default send syscall.SIGTERM
// kill -2 is syscall.SIGINT
// kill -9 is syscall.SIGKILL but can't be catch, so don't need add it
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
log.Println("Shutting down server...")
}
const (
nodeBits = 10
stepBits = 12
nodeMax = -1 ^ (-1 << nodeBits)
stepMask int64 = -1 ^ (-1 << stepBits)
timeShift uint8 = nodeBits + stepBits
nodeShift uint8 = stepBits
)
const encodeBase58Map = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
var decodeBase58Map [256]byte
// A JSONSyntaxError is returned from UnmarshalJSON if an invalid ID is provided.
type JSONSyntaxError struct{ original []byte }
func (j JSONSyntaxError) Error() string {
return fmt.Sprintf("invalid snowflake ID %q", string(j.original))
}
// Create a map for decoding Base58. This speeds up the process tremendously.
func init() {
for i := 0; i < len(encodeBase58Map); i++ {
decodeBase58Map[i] = 0xFF
}
for i := 0; i < len(encodeBase58Map); i++ {
decodeBase58Map[encodeBase58Map[i]] = byte(i)
}
}
// ErrInvalidBase58 is returned by ParseBase58 when given an invalid []byte
var ErrInvalidBase58 = errors.New("invalid base58")
// Epoch is set to the twitter snowflake epoch of 2006-03-21:20:50:14 GMT
// You may customize this to set a different epoch for your application.
var Epoch int64 = 1288834974657
// A Node struct holds the basic information needed for a snowflake generator
// node
type Sequence struct {
sync.Mutex
time int64
node int64
step int64
}
// An ID is a custom type used for a snowflake ID. This is used so we can
// attach methods onto the ID.
type ID int64
// NewNode returns a new snowflake node that can be used to generate snowflake
// IDs
func NewSequence(node int64) (*Sequence, error) {
if node < 0 || node > nodeMax {
return nil, errors.New("Node number must be between 0 and 1023")
}
return &Sequence{
time: 0,
node: node,
step: 0,
}, nil
}
// Generate creates and returns a unique snowflake ID
func (n *Sequence) Generate() ID {
n.Lock()
now := time.Now().UnixNano() / 1000000
if n.time == now {
n.step = (n.step + 1) & stepMask
if n.step == 0 {
for now <= n.time {
now = time.Now().UnixNano() / 1000000
}
}
} else {
n.step = 0
}
n.time = now
r := ID((now-Epoch)<<timeShift |
(n.node << nodeShift) |
(n.step),
)
n.Unlock()
return r
}
// Int64 returns an int64 of the snowflake ID
func (f ID) Int64() int64 {
return int64(f)
}
// String returns a string of the snowflake ID
func (f ID) String() string {
return strconv.FormatInt(int64(f), 10)
}
// Base2 returns a string base2 of the snowflake ID
func (f ID) Base2() string {
return strconv.FormatInt(int64(f), 2)
}
// Base36 returns a base36 string of the snowflake ID
func (f ID) Base36() string {
return strconv.FormatInt(int64(f), 36)
}
// Base58 returns a base58 string of the snowflake ID
func (f ID) Base58() string {
if f < 58 {
return string(encodeBase58Map[f])
}
b := make([]byte, 0, 11)
for f >= 58 {
b = append(b, encodeBase58Map[f%58])
f /= 58
}
b = append(b, encodeBase58Map[f])
for x, y := 0, len(b)-1; x < y; x, y = x+1, y-1 {
b[x], b[y] = b[y], b[x]
}
return string(b)
}
// ParseBase58 parses a base58 []byte into a snowflake ID
func ParseBase58(b []byte) (ID, error) {
var id int64
for i := range b {
if decodeBase58Map[b[i]] == 0xFF {
return -1, ErrInvalidBase58
}
id = id*58 + int64(decodeBase58Map[b[i]])
}
return ID(id), nil
}
// Base64 returns a base64 string of the snowflake ID
func (f ID) Base64() string {
return base64.StdEncoding.EncodeToString(f.Bytes())
}
// Bytes returns a byte slice of the snowflake ID
func (f ID) Bytes() []byte {
return []byte(f.String())
}
// IntBytes returns an array of bytes of the snowflake ID, encoded as a
// big endian integer.
func (f ID) IntBytes() [8]byte {
var b [8]byte
binary.BigEndian.PutUint64(b[:], uint64(f))
return b
}
// Time returns an int64 unix timestamp of the snowflake ID time
func (f ID) Time() int64 {
return (int64(f) >> 22) + Epoch
}
// Node returns an int64 of the snowflake ID node number
func (f ID) Node() int64 {
return int64(f) & 0x00000000003FF000 >> nodeShift
}
// Step returns an int64 of the snowflake step (or sequence) number
func (f ID) Step() int64 {
return int64(f) & 0x0000000000000FFF
}
// MarshalJSON returns a json byte array string of the snowflake ID.
func (f ID) MarshalJSON() ([]byte, error) {
buff := make([]byte, 0, 22)
buff = append(buff, '"')
buff = strconv.AppendInt(buff, int64(f), 10)
buff = append(buff, '"')
return buff, nil
}
// UnmarshalJSON converts a json byte array of a snowflake ID into an ID type.
func (f *ID) UnmarshalJSON(b []byte) error {
if len(b) < 3 || b[0] != '"' || b[len(b)-1] != '"' {
return JSONSyntaxError{b}
}
i, err := strconv.ParseInt(string(b[1:len(b)-1]), 10, 64)
if err != nil {
return err
}
*f = ID(i)
return nil
}
// GetDateInfoFromID ...
func GetDateInfoFromID(id int64) (year, month, day string) {
ts := ID(id).Time()
t := time.Unix(ts/1000, ts%1000)
year = fmt.Sprintf("%04d", t.Year())
month = fmt.Sprintf("%02d", t.Month())
day = fmt.Sprintf("%02d", t.Day())
return
}