package dbs import ( "encoding/json" "fmt" "strings" "time" "git.x2erp.com/qdy/go-svc-mcp/internal/mcp" ) func init() { mcp.Register("get_oracle_columns", "根据表名称获取Oracle表的所有字段相关信息", map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "table_name": map[string]interface{}{ "type": "string", "description": "表名称(支持大小写敏感)", }, "schema": map[string]interface{}{ "type": "string", "description": "模式名称(默认为当前用户)", "default": "", }, "include_comments": map[string]interface{}{ "type": "boolean", "description": "是否包含字段注释", "default": true, }, "database_key": map[string]interface{}{ "type": "string", "description": "数据库配置键名(如:business),可选,默认使用主数据库", "enum": []string{"warehouse", "business"}, "default": "warehouse", }, }, "required": []string{"table_name"}, }, func(input json.RawMessage, deps *mcp.ToolDependencies) (interface{}, error) { var params struct { TableName string `json:"table_name"` Schema string `json:"schema"` IncludeComments bool `json:"include_comments"` DatabaseKey string `json:"database_key"` } if len(input) > 0 { if err := json.Unmarshal(input, ¶ms); err != nil { return nil, err } } // 获取数据库工厂 dbFactory, err := GetDBFactory(params.DatabaseKey, deps) if err != nil { return nil, err } // 获取数据库类型,确保是Oracle dbType := dbFactory.GetDBType() if dbType != "oracle" { return nil, fmt.Errorf("当前数据库类型为 %s,此工具仅支持Oracle数据库", dbType) } // 清理表名和模式名 tableName := strings.TrimSpace(params.TableName) schema := strings.TrimSpace(params.Schema) if tableName == "" { return nil, fmt.Errorf("表名称不能为空") } // 构建查询SQL var query string if schema == "" { // 查询当前用户下的表字段信息 if params.IncludeComments { query = ` SELECT c.column_id, c.column_name, c.data_type, c.data_length, c.data_precision, c.data_scale, c.nullable, c.data_default as column_default, cc.comments as column_comment FROM user_tab_columns c LEFT JOIN user_col_comments cc ON c.table_name = cc.table_name AND c.column_name = cc.column_name WHERE c.table_name = UPPER(:1) ORDER BY c.column_id` } else { query = ` SELECT column_id, column_name, data_type, data_length, data_precision, data_scale, nullable, data_default as column_default FROM user_tab_columns WHERE table_name = UPPER(:1) ORDER BY column_id` } } else { // 查询指定模式下的表字段信息 if params.IncludeComments { query = ` SELECT c.column_id, c.column_name, c.data_type, c.data_length, c.data_precision, c.data_scale, c.nullable, c.data_default as column_default, cc.comments as column_comment FROM all_tab_columns c LEFT JOIN all_col_comments cc ON c.owner = cc.owner AND c.table_name = cc.table_name AND c.column_name = cc.column_name WHERE c.table_name = UPPER(:1) AND c.owner = UPPER(:2) ORDER BY c.column_id` } else { query = ` SELECT column_id, column_name, data_type, data_length, data_precision, data_scale, nullable, data_default as column_default FROM all_tab_columns WHERE table_name = UPPER(:1) AND owner = UPPER(:2) ORDER BY column_id` } } // 执行查询 var results []map[string]interface{} if schema == "" { results, err = dbFactory.QuerySliceMapWithParams(query, tableName) } else { results, err = dbFactory.QuerySliceMapWithParams(query, tableName, schema) } if err != nil { return nil, fmt.Errorf("查询表字段信息失败: %v", err) } if len(results) == 0 { // 尝试查询表是否存在 var tableExistsQuery string if schema == "" { tableExistsQuery = `SELECT COUNT(*) as table_count FROM user_tables WHERE table_name = UPPER(:1)` } else { tableExistsQuery = `SELECT COUNT(*) as table_count FROM all_tables WHERE table_name = UPPER(:1) AND owner = UPPER(:2)` } var tableCheckResults []map[string]interface{} if schema == "" { tableCheckResults, err = dbFactory.QuerySliceMapWithParams(tableExistsQuery, tableName) } else { tableCheckResults, err = dbFactory.QuerySliceMapWithParams(tableExistsQuery, tableName, schema) } if err == nil && len(tableCheckResults) > 0 { if count, ok := tableCheckResults[0]["table_count"].(int64); ok && count == 0 { return nil, fmt.Errorf("表 '%s' 不存在", tableName) } } return nil, fmt.Errorf("表 '%s' 存在但没有字段信息或表为空", tableName) } // 处理字段信息,确保null值转换为空字符串 for i := range results { // 处理NULLABLE字段 if nullable, ok := results[i]["nullable"].(string); ok { results[i]["is_nullable"] = nullable == "Y" delete(results[i], "nullable") } // 处理注释字段 if params.IncludeComments { if comment, ok := results[i]["column_comment"]; ok && comment == nil { results[i]["column_comment"] = "" } } // 处理默认值 if defaultValue, ok := results[i]["column_default"]; ok && defaultValue == nil { results[i]["column_default"] = "" } // 构建完整的数据类型 dataType := "" if dt, ok := results[i]["data_type"].(string); ok { dataType = dt if precision, ok := results[i]["data_precision"].(int64); ok && precision > 0 { if scale, ok := results[i]["data_scale"].(int64); ok && scale > 0 { dataType = fmt.Sprintf("%s(%d,%d)", dt, precision, scale) } else { dataType = fmt.Sprintf("%s(%d)", dt, precision) } } else if length, ok := results[i]["data_length"].(int64); ok && length > 0 { // 对于VARCHAR2/CHAR等类型 dataType = fmt.Sprintf("%s(%d)", dt, length) } results[i]["full_data_type"] = dataType } } // 获取表注释 var tableComment string if schema == "" { tableCommentQuery := `SELECT comments FROM user_tab_comments WHERE table_name = UPPER(:1)` commentResults, err := dbFactory.QuerySliceMapWithParams(tableCommentQuery, tableName) if err == nil && len(commentResults) > 0 { if comment, ok := commentResults[0]["comments"].(string); ok { tableComment = comment } } } else { tableCommentQuery := `SELECT comments FROM all_tab_comments WHERE table_name = UPPER(:1) AND owner = UPPER(:2)` commentResults, err := dbFactory.QuerySliceMapWithParams(tableCommentQuery, tableName, schema) if err == nil && len(commentResults) > 0 { if comment, ok := commentResults[0]["comments"].(string); ok { tableComment = comment } } } return map[string]interface{}{ "tenant_id": deps.ReqCtx.TenantID, "user_id": deps.ReqCtx.UserID, "database_type": dbType, "database_name": dbFactory.GetDatabaseName(), "schema": schema, "table_name": tableName, "table_comment": tableComment, "include_comments": params.IncludeComments, "columns": results, "total_columns": len(results), "timestamp": time.Now().Format(time.RFC3339), }, nil }, ) }