feat: 支持执行多条sql

This commit is contained in:
meilin.huang
2022-11-02 19:27:40 +08:00
committed by 刘宗洋
parent 4475972af3
commit 20beb30dd8
5 changed files with 60 additions and 18 deletions

View File

@@ -36,7 +36,7 @@
<el-table-column label="操作" width>
<template #default="scope">
<el-link type="primary" @click="showDatabases(scope.row.id, scope.row)" plain size="small"
<el-link type="primary" @click="showDatabases(scope.row.id)" plain size="small"
:underline="false">数据库</el-link>
</template>
</el-table-column>

View File

@@ -128,27 +128,43 @@ func (d *Db) ExecSql(rc *ctx.ReqCtx) {
dbInstance := d.DbApp.GetDbInstance(id, db)
biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbInstance.TagPath), "%s")
rc.ReqParam = fmt.Sprintf("db: %d:%s | sql: %s", id, db, form.Sql)
biz.NotEmpty(form.Sql, "sql不能为空")
// 去除前后空格及换行符
sql := strings.TrimFunc(form.Sql, func(r rune) bool {
s := string(r)
return s == " " || s == "\n"
})
sql := utils.StrTrimSpaceAndBr(form.Sql)
rc.ReqParam = fmt.Sprintf("db: %d:%s | sql: %s", id, db, sql)
biz.NotEmpty(sql, "sql不能为空")
execRes, err := d.DbSqlExecApp.Exec(&application.DbSqlExecReq{
execReq := &application.DbSqlExecReq{
DbId: id,
Db: db,
Sql: sql,
Remark: form.Remark,
DbInstance: dbInstance,
LoginAccount: rc.LoginAccount,
})
biz.ErrIsNilAppendErr(err, "执行失败: %s")
}
sqls := strings.Split(sql, ";\n")
isMulti := len(sqls) > 1
var execResAll *application.DbSqlExecRes
for _, s := range sqls {
s = utils.StrTrimSpaceAndBr(s)
// 多条执行,如果有查询语句,则跳过
if isMulti && strings.HasPrefix(strings.ToLower(s), "select") {
continue
}
execReq.Sql = s
execRes, err := d.DbSqlExecApp.Exec(execReq)
biz.ErrIsNilAppendErr(err, "执行失败: %s")
if execResAll == nil {
execResAll = execRes
} else {
execResAll.Merge(execRes)
}
}
colAndRes := make(map[string]interface{})
colAndRes["colNames"] = execRes.ColNames
colAndRes["res"] = execRes.Res
colAndRes["colNames"] = execResAll.ColNames
colAndRes["res"] = execResAll.Res
rc.ResData = colAndRes
}

View File

@@ -358,7 +358,7 @@ func getDsn(d *entity.Db, db string) string {
var dsn string
if d.Type == entity.DbTypeMysql {
// 更多参数参考https://github.com/go-sql-driver/mysql#dsn-data-source-name
dsn = fmt.Sprintf("%s:%s@%s(%s:%d)/%s?timeout=8s&multiStatements=true", d.Username, d.Password, d.Network, d.Host, d.Port, db)
dsn = fmt.Sprintf("%s:%s@%s(%s:%d)/%s?timeout=8s", d.Username, d.Password, d.Network, d.Host, d.Port, db)
if d.Params != "" {
dsn = fmt.Sprintf("%s&%s", dsn, d.Params)
}

View File

@@ -25,6 +25,21 @@ type DbSqlExecRes struct {
Res []map[string]interface{}
}
// 合并执行结果主要用于执行多条sql使用
func (d *DbSqlExecRes) Merge(execRes *DbSqlExecRes) {
canMerge := len(d.ColNames) == len(execRes.ColNames)
if !canMerge {
return
}
// 列名不一致,则不合并
for i, colName := range d.ColNames {
if execRes.ColNames[i] != colName {
return
}
}
d.Res = append(d.Res, execRes.Res...)
}
type DbSqlExec interface {
// 执行sql
Exec(execSqlReq *DbSqlExecReq) (*DbSqlExecRes, error)
@@ -187,16 +202,19 @@ func doInsert(insert *sqlparser.Insert, execSqlReq *DbSqlExecReq, dbSqlExec *ent
func doExec(sql string, dbInstance *DbInstance) (*DbSqlExecRes, error) {
rowsAffected, err := dbInstance.Exec(sql)
execRes := "success"
if err != nil {
return nil, err
execRes = err.Error()
}
res := make([]map[string]interface{}, 0)
resData := make(map[string]interface{})
resData["影响条数"] = rowsAffected
resData["rowsAffected"] = rowsAffected
resData["sql"] = sql
resData["result"] = execRes
res = append(res, resData)
return &DbSqlExecRes{
ColNames: []string{"影响条数"},
ColNames: []string{"sql", "rowsAffected", "result"},
Res: res,
}, nil
}

View File

@@ -18,6 +18,14 @@ func StrTrim(str string) string {
return strings.Trim(str, " ")
}
// 去除字符串左右空字符与\n换行
func StrTrimSpaceAndBr(str string) string {
return strings.TrimFunc(str, func(r rune) bool {
s := string(r)
return s == " " || s == "\n"
})
}
func SubString(str string, begin, end int) (substr string) {
// 将字符串的转换成[]rune
rs := []rune(str)