{"id":48433822,"url":"https://github.com/zachvictor/sqlinsert","last_synced_at":"2026-04-06T12:01:05.713Z","repository":{"id":49381208,"uuid":"517273698","full_name":"zachvictor/sqlinsert","owner":"zachvictor","description":"Generate SQL INSERT statement from Go struct with struct tags. Works with standard database/sql package.","archived":false,"fork":false,"pushed_at":"2022-08-07T01:56:08.000Z","size":45,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-14T12:26:42.848Z","etag":null,"topics":["bind-parameters","database","go","golang","memsql","mysql","oracle","oracle-db","postgres","postgresql","singlestore","sql","sqlserver","tsql"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zachvictor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-24T08:58:16.000Z","updated_at":"2023-08-03T21:04:36.000Z","dependencies_parsed_at":"2022-08-12T20:11:05.811Z","dependency_job_id":null,"html_url":"https://github.com/zachvictor/sqlinsert","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/zachvictor/sqlinsert","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachvictor%2Fsqlinsert","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachvictor%2Fsqlinsert/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachvictor%2Fsqlinsert/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachvictor%2Fsqlinsert/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zachvictor","download_url":"https://codeload.github.com/zachvictor/sqlinsert/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachvictor%2Fsqlinsert/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31471466,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T08:36:52.050Z","status":"ssl_error","status_checked_at":"2026-04-06T08:36:51.267Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bind-parameters","database","go","golang","memsql","mysql","oracle","oracle-db","postgres","postgresql","singlestore","sql","sqlserver","tsql"],"created_at":"2026-04-06T12:01:05.027Z","updated_at":"2026-04-06T12:01:05.707Z","avatar_url":"https://github.com/zachvictor.png","language":"Go","readme":"# sqlinsert\nGenerate a SQL INSERT statement with bind parameters directly from a Go struct.\n[![Go Reference](https://pkg.go.dev/badge/github.com/zachvictor/sqlinsert.svg)](https://pkg.go.dev/github.com/zachvictor/sqlinsert)\n\n## Features\n* Define column names in struct tags.\n* Struct values become bind arguments.\n* Use SQL outputs and Args slice piecemeal. Or, use `Insert()`/`InsertContext()` with a `sql.Conn`, `sql.DB`, or\n`sql.Tx` to execute the INSERT statement directly.\n* Works seamlessly with Go standard library [database/sql](https://pkg.go.dev/database/sql) package. \n* Supports bind parameter token types of MySQL, PostgreSQL, Oracle, SingleStore (MemSQL), SQL Server (T-SQL), and their \nequivalents.\n* Supports custom struct tags and token types.\n* Supports Go 1.8 to 1.19.\n* Test coverage: 100% files, 97.5% statements. Tested on Go 1.15, 1.17, and 1.18.\n\n## Example\n### Given\n```sql\nCREATE TABLE candy (\n    id           CHAR(36) NOT NULL\n    candy_name   VARCHAR(255) NOT NULL\n    form_factor  VARCHAR(255) NOT NULL\n    description  VARCHAR(255) NOT NULL\n    manufacturer VARCHAR(255) NOT NULL\n    weight_grams DECIMAL(9, 3) NOT NULL\n    ts DATETIME  NOT NULL\n)\n```\n\n```go\ntype CandyInsert struct {\n    Id          string    `col:\"id\"`\n    Name        string    `col:\"candy_name\"`\n    FormFactor  string    `col:\"form_factor\"`\n    Description string    `col:\"description\"`\n    Mfr         string    `col:\"manufacturer\"`\n    Weight      float64   `col:\"weight_grams\"`\n    Timestamp   time.Time `col:\"ts\"`\n}\n\nvar rec = CandyInsert{\n    Id:          `c0600afd-78a7-4a1a-87c5-1bc48cafd14e`,\n    Name:        `Gougat`,\n    FormFactor:  `Package`,\n    Description: `tastes like gopher feed`,\n    Mfr:         `Gouggle`,\n    Weight:      1.16180,\n    Timestamp:   time.Time{},\n}\n```\n\n### Before\n```go\nstmt, _ := db.Prepare(`INSERT INTO candy\n    (id, candy_name, form_factor, description, manufacturer, weight_grams, ts)\n    VALUES (?, ?, ?, ?, ?, ?, ?)`)\n_, err := stmt.Exec(candyInsert.Id, candyInsert.Name, candyInsert.FormFactor,\n\tcandyInsert.Description, candyInsert.Mfr, candyInsert.Weight, candyInsert.Timestamp)\n```\n\n### After\n```go\nins := sqlinsert.Insert{`candy`, \u0026rec}\n_, err := ins.Insert(db)\n```\n\n### I want to see the SQL\nQuestion-mark (?) VALUES-tokens are the default:\n```go\nfmt.Println(ins.SQL())\n// INSERT INTO candy (id,candy_name,form_factor,description,manufacturer,weight_grams,ts) VALUES (?,?,?,?,?,?,?)\n```\n\nYou can change the token type. For example, for PostgreSQL:\n```go\nsqlinsert.UseTokenType = OrdinalNumberTokenType\nfmt.Println(ins.SQL())\n// INSERT INTO candy (id,candy_name,form_factor,description,manufacturer,weight_grams,ts) VALUES ($1,$2,$3,$4,$5,$6,$7)\n```\n\n### I want to see the args\n\n```go\npretty.Println(ins.Args())\n```\nyields (using [github.com/kr/pretty](https://github.com/kr/pretty)):\n```\n[]interface {}{\n    \"c0600afd-78a7-4a1a-87c5-1bc48cafd14e\",\n    \"Gougat\",\n    \"Package\",\n    \"tastes like gopher feed\",\n    \"Gouggle\",\n    float64(1.1618),\n    time.Date(1, time.January, 1, 0, 0, 0, 0, time.UTC),\n}\n```\n\n### I want to use database/sql apparatus\n```go\nstmt, _ := db.Prepare(ins.SQL())\nresult, _ := stmt.Exec(ins.Args()...)\n```\n\n\n## This is a helper\n\n`sqlinsert` is fundamentally a helper for [database/sql](https://pkg.go.dev/database/sql).\nIt simply maps struct fields to INSERT elements:\n* struct tags\n=\u003e SQL columns and tokens `string`\n=\u003e [Prepare](https://pkg.go.dev/database/sql@go1.17#DB.Prepare) `query string`\n* struct values\n=\u003e bind args `[]interface{}`\n=\u003e [Exec](https://pkg.go.dev/database/sql@go1.17#Stmt.Exec) `args ...interface{}`\n([Go 1.18](https://pkg.go.dev/database/sql@go1.18#DB.ExecContext)+ `args ...any`)\n\n### Use only what you need\nAll aspects of SQL INSERT remain in your control:\n* _I just want the column names for my SQL._ `Insert.Columns()`\n* _I just want the parameter-tokens for my SQL._ `Insert.Params()`\n* _I just want the bind args for my Exec() call._ `Insert.Args()`\n* _I just want a Prepare-Exec wrapper._ `Insert.Insert()`\n\n## This is not an ORM\n\n### Hide nothing\nUnlike ORMs, `sqlinsert` does **not** create an abstraction layer over SQL relations, nor does it restructure SQL\nfunctions.\nThe aim is to keep it simple and hide nothing.\n\n### Let SQL be great\nSQL’s INSERT is already as close to functionally pure as possible. Why would we change that? Its simplicity and\ndirectness are its power.\n\n### Let database/sql be great\nSome database vendors support collection types for bind parameters, some don’t.\nSome database drivers support slices for bind args, some don’t.\nThe complexity of this reality is met admirably by [database/sql](https://pkg.go.dev/database/sql)\nwith the _necessary_ amount of flexibility and abstraction:\n_flexibility_ in open-ended SQL;\n_abstraction_ in the variadic `args ...interface{}` for bind args.\nIn this way, [database/sql](https://pkg.go.dev/database/sql) respects INSERT’s power,\nhiding nothing even as it tolerates the vagaries of bind-parameter handling among database vendors and drivers.\n\n### Let Go be great\nGo structs support ordered fields, strong types, and field metadata via [tags](https://go.dev/ref/spec#Tag) and\n[reflection](https://pkg.go.dev/reflect#StructTag).\nIn these respects, the Go struct can encapsulate the information of a SQL INSERT-row perfectly and completely.\n`sqlinsert` uses these features of Go structs to makes your SQL INSERT experience more Go-idiomatic.\n\n## Limitations of the Prepare-Exec wrappers\n`Insert.Insert` and `Insert.InsertContext` are for simple binding _only._\nIn the spirit of “hide nothing,” these do _not_ support SQL operations in the `VALUES` clause.\nIf you require, say—\n```sql\nINSERT INTO foo (bar, baz, oof) VALUES (some_function(?), REPLACE(?, 'oink', 'moo'), ? + ?);\n```\n—then you can use `sqlinsert.Insert` methods piecemeal.\nFor example, use `Insert.Columns` to build the column list for `Prepare`\nand `Insert.Args` to marshal the args for `Exec`/`ExecContext`.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzachvictor%2Fsqlinsert","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzachvictor%2Fsqlinsert","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzachvictor%2Fsqlinsert/lists"}