mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-22 00:42:47 +08:00
🐛 fix(query-editor): 补齐SQL Server冗余结果集过滤
- 为 SQL Server 原生多结果集缺失 statementIndex 的场景补齐结果归属 - 修复单条 SELECT 查询尾随 affectedRows 结果被误渲染为额外结果页签的问题 - 补充前后端回归测试并保持存储过程多结果集展示不变
This commit is contained in:
@@ -1038,6 +1038,9 @@ func (a *App) DBQueryMulti(config connection.ConnectionConfig, dbName string, qu
|
||||
logger.Warnf("DBQueryMulti 原生多结果集返回空结果,将回退逐条执行:%s SQL片段=%q", formatConnSummary(runConfig), sqlSnippet(query))
|
||||
results = nil
|
||||
}
|
||||
if useNativeMultiResult && results != nil {
|
||||
normalizeNativeResultStatementIndexes(runConfig.Type, statements, results)
|
||||
}
|
||||
|
||||
// 驱动支持多结果集,直接返回
|
||||
if results != nil {
|
||||
@@ -1276,6 +1279,33 @@ func (a *App) DBQueryMulti(config connection.ConnectionConfig, dbName string, qu
|
||||
return connection.QueryResult{Success: true, Data: resultSets, QueryID: queryID, Message: fallbackMsg}
|
||||
}
|
||||
|
||||
func normalizeNativeResultStatementIndexes(dbType string, statements []string, results []connection.ResultSetData) {
|
||||
if !isSQLServerDBType(dbType) || len(results) == 0 {
|
||||
return
|
||||
}
|
||||
hasExplicitStatementIndex := false
|
||||
for _, result := range results {
|
||||
if result.StatementIndex > 0 {
|
||||
hasExplicitStatementIndex = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasExplicitStatementIndex {
|
||||
return
|
||||
}
|
||||
|
||||
switch {
|
||||
case len(statements) <= 1:
|
||||
for idx := range results {
|
||||
results[idx].StatementIndex = 1
|
||||
}
|
||||
case len(results) == len(statements):
|
||||
for idx := range results {
|
||||
results[idx].StatementIndex = idx + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func shouldUseNativeMultiResultBatch(dbType string, statements []string, allReadOnly bool) bool {
|
||||
if allReadOnly {
|
||||
return true
|
||||
|
||||
@@ -1525,6 +1525,51 @@ func TestDBQueryMultiKeepsAllResultSetsFromSingleSQLServerStatement(t *testing.T
|
||||
}
|
||||
}
|
||||
|
||||
func TestDBQueryMultiNormalizesSingleSQLServerSelectAffectedRowsStatementIndex(t *testing.T) {
|
||||
originalNewDatabaseFunc := newDatabaseFunc
|
||||
t.Cleanup(func() {
|
||||
newDatabaseFunc = originalNewDatabaseFunc
|
||||
})
|
||||
|
||||
query := "select * from c_dddw"
|
||||
fakeDB := &fakeBatchWriteDB{
|
||||
multiResult: map[string][]connection.ResultSetData{
|
||||
query: {
|
||||
{
|
||||
Rows: []map[string]interface{}{{"dddwno": "001", "dddwlist": "demo"}},
|
||||
Columns: []string{"dddwno", "dddwlist"},
|
||||
},
|
||||
{
|
||||
Rows: []map[string]interface{}{{"affectedRows": int64(846)}},
|
||||
Columns: []string{"affectedRows"},
|
||||
},
|
||||
},
|
||||
},
|
||||
queryErr: map[string]error{},
|
||||
}
|
||||
newDatabaseFunc = func(dbType string) (db.Database, error) {
|
||||
return fakeDB, nil
|
||||
}
|
||||
|
||||
app := NewAppWithSecretStore(secretstore.NewUnavailableStore("test"))
|
||||
config := connection.ConnectionConfig{Type: "sqlserver", Host: "127.0.0.1", Port: 1433, User: "sa"}
|
||||
|
||||
result := app.DBQueryMulti(config, "hydee", query, "sqlserver-select-affectedrows-index-test")
|
||||
if !result.Success {
|
||||
t.Fatalf("expected DBQueryMulti success, got failure: %s", result.Message)
|
||||
}
|
||||
resultSets, ok := result.Data.([]connection.ResultSetData)
|
||||
if !ok {
|
||||
t.Fatalf("expected []connection.ResultSetData, got %T", result.Data)
|
||||
}
|
||||
if len(resultSets) != 2 {
|
||||
t.Fatalf("expected two result sets, got %#v", resultSets)
|
||||
}
|
||||
if resultSets[0].StatementIndex != 1 || resultSets[1].StatementIndex != 1 {
|
||||
t.Fatalf("expected select result and trailing affectedRows result to share statementIndex=1, got %#v", resultSets)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDBQueryMultiTreatsBareSQLServerProcedureCallAsQueryFirst(t *testing.T) {
|
||||
originalNewDatabaseFunc := newDatabaseFunc
|
||||
t.Cleanup(func() {
|
||||
|
||||
Reference in New Issue
Block a user