diff --git a/dao/dbm.go b/dao/dbm.go index 6ba4102..f25bde3 100644 --- a/dao/dbm.go +++ b/dao/dbm.go @@ -155,3 +155,58 @@ func FindAllSQLRunHistory() ([]proto.SQLRunHistory, error) { } return histories, nil } + +func RunSQLWithOrder(sql string, db_ *gorm.DB) (result proto.SQLResult, err error) { + var db2 *gorm.DB + // 保留 Debug 模式 + if proto.Config.SERVER_SQL_LOG { + db2 = db_.Debug() + } else { + db2 = db_ + } + + // 执行 SQL 并获取底层 Rows 对象 + rows, err := db2.Raw(sql).Rows() + if err != nil { + return result, err + } + defer rows.Close() // 确保关闭 Rows + + // 获取列名顺序(关键:这里的顺序与 SQL 查询的列顺序一致) + columns, err := rows.Columns() + if err != nil { + return result, err + } + result.Columns = columns // 保存列名顺序 + + // 遍历每行数据 + for rows.Next() { + // 准备接收每行数据的容器(按列顺序) + values := make([]interface{}, len(columns)) + valuePtrs := make([]interface{}, len(columns)) // 用于 Scan 的指针切片 + + // 为每个列绑定指针(Scan 要求传入指针) + for i := range values { + valuePtrs[i] = &values[i] + } + + // 扫描当前行数据到指针切片 + if err2 := rows.Scan(valuePtrs...); err2 != nil { + return result, err2 + } + + // 将当前行数据存入 map(便于按列名访问) + rowMap := make(map[string]interface{}) + for i, col := range columns { + rowMap[col] = values[i] + } + result.Rows = append(result.Rows, rowMap) + } + + // 检查遍历过程中是否有错误 + if err = rows.Err(); err != nil { + return result, err + } + + return result, nil +} diff --git a/proto/dbm.go b/proto/dbm.go index eeb8ca7..744d245 100644 --- a/proto/dbm.go +++ b/proto/dbm.go @@ -67,3 +67,9 @@ type GetSQLRunHistoryReq struct { DB_ID uint `json:"db_id" form:"db_id"` // 数据库ID GET_TYPE int `json:"get_type" form:"get_type"` // 获取类型: 0获取自己,1为获取全部(管理员权限) } + +// SQLResult 包含查询结果的列名顺序和对应数据 +type SQLResult struct { + Columns []string // 列名顺序(与 SQL 查询的列顺序一致) + Rows []map[string]interface{} // 每行数据(map 便于按列名访问) +}