使用Golang向MS SQL插入DateTime值的技术问询
解决Golang向MS SQL插入DateTime值的问题
你的代码目前存在几个关键问题,我来一步步帮你修正:
问题分析
- SQL注入风险:用
fmt.Sprintf拼接SQL语句是不安全的做法——虽然这里的时间是系统生成的,但如果后续扩展到用户输入的变量,会直接暴露在SQL注入攻击下。 - 日期格式兼容性问题:手动将
time.Time格式化为RFC3339字符串,可能会和MS SQL的datetime字段格式不兼容(部分版本的SQL Server对某些字符串格式解析会出错)。 - 语法错误:你的
db.ExecContext调用参数有误,写成了t...,这明显是笔误,应该传递正确的SQL语句和参数。
正确实现方式
最佳实践是使用参数化查询,让Go的MS SQL驱动自动处理日期类型的转换,同时彻底避免SQL注入风险。以下是修正后的完整代码:
import ( "context" "database/sql" "fmt" "time" ) func timeSample(db *sql.DB) error { ctx := context.Background() // 使用命名参数的参数化查询,清晰且安全 tsql := `INSERT INTO [dbo].[TimeSample] ([ModifiedDate]) VALUES (@ModifiedDate);` // 直接传递time.Time类型,驱动会自动转换为MS SQL的datetime格式 result, err := db.ExecContext(ctx, tsql, sql.Named("ModifiedDate", time.Now())) if err != nil { // 用错误包装保留原始错误信息,便于排查 return fmt.Errorf("插入时间记录失败: %w", err) } // 可选:可以查看插入的行数,验证操作结果 rowsAffected, err := result.RowsAffected() if err != nil { return fmt.Errorf("获取影响行数失败: %w", err) } fmt.Printf("成功插入 %d 条记录\n", rowsAffected) return nil }
关键说明
- 参数化查询的优势:驱动会负责参数的转义、类型转换,完全避免SQL注入,同时确保日期格式符合MS SQL的要求。
- 直接传递time.Time:MS SQL的官方驱动(
github.com/denisenkom/go-mssqldb)支持将Go的time.Time直接映射到SQL的datetime/datetime2类型,不需要手动格式化字符串。 - 错误处理:使用
fmt.Errorf的%w包装错误,保留原始错误栈,方便后续调试问题。
内容的提问来源于stack exchange,提问作者Flea
相关产品推荐
相关产品推荐

