Golang中如何将HTML5日期输入数据插入MySQL语句

Golang中如何将HTML5日期输入数据插入MySQL语句 大家好,

我遇到了一个问题。我的Go代码通过静态查询输出HTML内容,这部分代码运行得相当快。但是我在HTML端添加了一个日历控件,现在遇到了将日历选择的信息传回Go代码的问题。

以下是我想要修改的MySQL语句部分:

SELECT
full_name,
SUM(CASE WHEN foo_agent_log.user IS NULL THEN 0 ELSE 1
AND event_time >= '**2018-04-21** 00:00:00' AND event_time <= '**2018-04-21** 23:59:00' END)
FROM foo
ORDER by full_name asc

查询中加粗的部分正是我想要修改的内容。

我对Golang还比较陌生,没有在这里放置所有代码,因为我不确定问题的空间限制。感谢任何帮助。


更多关于Golang中如何将HTML5日期输入数据插入MySQL语句的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

我认为这里非常关键的是要看你打算如何存储数据,因为这正是导致问题的原因(至少我是这样理解的)。

我建议将代码粘贴到 gist 上,否则很难追踪这个问题。

更多关于Golang中如何将HTML5日期输入数据插入MySQL语句的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


HTML 内容没有正确显示。让我尝试另一种方式。

        <form>
        <b>Begining Date:</b>
        <input type="date" id="Bdate" name={{.BDate}}  size="20" />
        <b>End Date:</b>
        <input type="date" id="Edate" name={{.EDate}}   size="20" />
        <input type="button" value="Submit" name="B1"></p>
        </form>

在Golang中处理HTML5日期输入并将其用于MySQL查询,你需要使用database/sql包和适当的参数化查询来安全地处理用户输入。以下是完整的解决方案:

首先,创建HTML表单来接收日期输入:

<!DOCTYPE html>
<html>
<head>
    <title>日期查询</title>
</head>
<body>
    <form method="POST" action="/query">
        <label for="startDate">开始日期:</label>
        <input type="date" id="startDate" name="startDate" required>
        
        <label for="endDate">结束日期:</label>
        <input type="date" id="endDate" name="endDate" required>
        
        <button type="submit">查询</button>
    </form>
</body>
</html>

Go后端处理代码:

package main

import (
    "database/sql"
    "fmt"
    "html/template"
    "log"
    "net/http"
    "time"

    _ "github.com/go-sql-driver/mysql"
)

type QueryData struct {
    StartDate string
    EndDate   string
}

type Result struct {
    FullName string
    Count    int
}

func main() {
    http.HandleFunc("/", showForm)
    http.HandleFunc("/query", handleQuery)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

func showForm(w http.ResponseWriter, r *http.Request) {
    tmpl := template.Must(template.ParseFiles("form.html"))
    tmpl.Execute(w, nil)
}

func handleQuery(w http.ResponseWriter, r *http.Request) {
    if r.Method != "POST" {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }

    // 解析表单数据
    err := r.ParseForm()
    if err != nil {
        http.Error(w, "无法解析表单", http.StatusBadRequest)
        return
    }

    startDate := r.FormValue("startDate")
    endDate := r.FormValue("endDate")

    // 验证日期格式
    if !isValidDate(startDate) || !isValidDate(endDate) {
        http.Error(w, "无效的日期格式", http.StatusBadRequest)
        return
    }

    // 连接MySQL数据库
    db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/database_name")
    if err != nil {
        http.Error(w, "数据库连接失败", http.StatusInternalServerError)
        return
    }
    defer db.Close()

    // 构建参数化查询
    query := `
        SELECT 
            full_name,
            SUM(CASE WHEN foo_agent_log.user IS NULL THEN 0 ELSE 1 END) as count
        FROM foo
        WHERE event_time >= ? AND event_time <= ?
        GROUP BY full_name
        ORDER BY full_name ASC
    `

    // 将日期转换为完整的日期时间格式
    startDateTime := startDate + " 00:00:00"
    endDateTime := endDate + " 23:59:59"

    // 执行查询
    rows, err := db.Query(query, startDateTime, endDateTime)
    if err != nil {
        http.Error(w, "查询执行失败", http.StatusInternalServerError)
        return
    }
    defer rows.Close()

    var results []Result
    for rows.Next() {
        var r Result
        err := rows.Scan(&r.FullName, &r.Count)
        if err != nil {
            http.Error(w, "数据读取失败", http.StatusInternalServerError)
            return
        }
        results = append(results, r)
    }

    // 输出结果
    fmt.Fprintf(w, "<h2>查询结果 (%s 到 %s)</h2>", startDate, endDate)
    for _, result := range results {
        fmt.Fprintf(w, "<p>%s: %d</p>", result.FullName, result.Count)
    }
}

// 验证日期格式
func isValidDate(date string) bool {
    _, err := time.Parse("2006-01-02", date)
    return err == nil
}

如果你需要处理更复杂的日期范围,这里是一个使用time包处理日期的增强版本:

func handleQueryEnhanced(w http.ResponseWriter, r *http.Request) {
    if r.Method != "POST" {
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }

    err := r.ParseForm()
    if err != nil {
        http.Error(w, "无法解析表单", http.StatusBadRequest)
        return
    }

    startDate := r.FormValue("startDate")
    endDate := r.FormValue("endDate")

    // 使用time包解析和验证日期
    start, err := time.Parse("2006-01-02", startDate)
    if err != nil {
        http.Error(w, "无效的开始日期", http.StatusBadRequest)
        return
    }

    end, err := time.Parse("2006-01-02", endDate)
    if err != nil {
        http.Error(w, "无效的结束日期", http.StatusBadRequest)
        return
    }

    // 确保结束日期不小于开始日期
    if end.Before(start) {
        http.Error(w, "结束日期不能早于开始日期", http.StatusBadRequest)
        return
    }

    db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/database_name")
    if err != nil {
        http.Error(w, "数据库连接失败", http.StatusInternalServerError)
        return
    }
    defer db.Close()

    query := `
        SELECT 
            full_name,
            SUM(CASE WHEN foo_agent_log.user IS NULL THEN 0 ELSE 1 END) as count
        FROM foo
        WHERE event_time >= ? AND event_time <= ?
        GROUP BY full_name
        ORDER BY full_name ASC
    `

    // 使用time包格式化日期时间
    startDateTime := start.Format("2006-01-02 15:04:05")
    endDateTime := end.Add(23*time.Hour + 59*time.Minute + 59*time.Second).Format("2006-01-02 15:04:05")

    rows, err := db.Query(query, startDateTime, endDateTime)
    if err != nil {
        http.Error(w, fmt.Sprintf("查询执行失败: %v", err), http.StatusInternalServerError)
        return
    }
    defer rows.Close()

    var results []Result
    for rows.Next() {
        var r Result
        err := rows.Scan(&r.FullName, &r.Count)
        if err != nil {
            http.Error(w, "数据读取失败", http.StatusInternalServerError)
            return
        }
        results = append(results, r)
    }

    // 检查遍历过程中的错误
    if err = rows.Err(); err != nil {
        http.Error(w, "行遍历错误", http.StatusInternalServerError)
        return
    }

    // 渲染结果
    tmpl := `
    <html>
    <body>
        <h2>查询结果 ({{.StartDate}} 到 {{.EndDate}})</h2>
        {{range .Results}}
        <p>{{.FullName}}: {{.Count}}</p>
        {{end}}
    </body>
    </html>
    `

    data := struct {
        StartDate string
        EndDate   string
        Results   []Result
    }{
        StartDate: startDate,
        EndDate:   endDate,
        Results:   results,
    }

    t := template.Must(template.New("result").Parse(tmpl))
    t.Execute(w, data)
}

关键要点:

  1. 使用参数化查询(?占位符)防止SQL注入
  2. 正确处理日期格式转换
  3. 添加输入验证确保数据安全性
  4. 使用database/sql包的标准方法处理数据库操作
  5. 正确处理错误和资源清理(defer关闭连接和结果集)
回到顶部