package dbs import ( "encoding/json" "fmt" "strings" "time" "git.x2erp.com/qdy/go-svc-mcp/internal/mcp" ) func init() { mcp.Register("get_oracle_data", "通过表名称获取Oracle表数据:只能接收表名称和分页查询参数分页参数数据获取数据不能超过10条", 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": "", }, "page": map[string]interface{}{ "type": "integer", "description": "页码(从1开始)", "default": 1, "minimum": 1, }, "page_size": map[string]interface{}{ "type": "integer", "description": "每页记录数(最大10条)", "default": 10, "minimum": 1, "maximum": 10, }, "order_by": map[string]interface{}{ "type": "string", "description": "排序字段(例如:column1 ASC, column2 DESC)", "default": "", }, "where_clause": map[string]interface{}{ "type": "string", "description": "WHERE条件(例如:status = 'ACTIVE')", "default": "", }, "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"` Page int `json:"page"` PageSize int `json:"page_size"` OrderBy string `json:"order_by"` WhereClause string `json:"where_clause"` DatabaseKey string `json:"database_key"` } if len(input) > 0 { if err := json.Unmarshal(input, ¶ms); err != nil { return nil, err } } // 设置默认值 if params.Page == 0 { params.Page = 1 } if params.PageSize == 0 { params.PageSize = 10 } // 确保每页记录数不超过10条 if params.PageSize > 10 { params.PageSize = 10 } // 获取数据库工厂 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("表名称不能为空") } // 验证表是否存在 tableExists := false 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 { return nil, fmt.Errorf("检查表是否存在失败: %v", err) } if len(tableCheckResults) > 0 { if count, ok := tableCheckResults[0]["table_count"].(int64); ok && count > 0 { tableExists = true } } if !tableExists { return nil, fmt.Errorf("表 '%s' 不存在", tableName) } // 构建带模式前缀的表名 fullTableName := tableName if schema != "" { fullTableName = fmt.Sprintf("%s.%s", schema, tableName) } // 构建WHERE子句 whereClause := "" if params.WhereClause != "" { whereClause = fmt.Sprintf("WHERE %s", params.WhereClause) } // 构建ORDER BY子句 orderByClause := "" if params.OrderBy != "" { orderByClause = fmt.Sprintf("ORDER BY %s", params.OrderBy) } // 计算分页偏移量 offset := (params.Page - 1) * params.PageSize // Oracle分页查询(使用ROWNUM) // 先获取总记录数 countQuery := fmt.Sprintf("SELECT COUNT(*) as total_count FROM %s %s", fullTableName, whereClause) countResults, err := dbFactory.QuerySliceMap(countQuery) if err != nil { return nil, fmt.Errorf("查询总记录数失败: %v", err) } totalCount := int64(0) if len(countResults) > 0 { if count, ok := countResults[0]["total_count"].(int64); ok { totalCount = count } } // 计算总页数 totalPages := 0 if totalCount > 0 { totalPages = int((totalCount + int64(params.PageSize) - 1) / int64(params.PageSize)) } // 如果请求的页码大于总页数,返回空结果 if params.Page > totalPages && totalPages > 0 { 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, "full_table_name": fullTableName, "page": params.Page, "page_size": params.PageSize, "total_count": totalCount, "total_pages": totalPages, "where_clause": params.WhereClause, "order_by": params.OrderBy, "data": []map[string]interface{}{}, "data_count": 0, "has_more": false, "timestamp": time.Now().Format(time.RFC3339), }, nil } // 构建数据查询(Oracle分页查询) dataQuery := "" if whereClause == "" && orderByClause == "" { // 简单查询,使用ROWNUM分页 dataQuery = fmt.Sprintf(` SELECT * FROM ( SELECT t.*, ROWNUM rn FROM %s t WHERE ROWNUM <= %d ) WHERE rn > %d`, fullTableName, offset+params.PageSize, offset) } else { // 复杂查询,需要子查询 if orderByClause == "" { // 有WHERE条件但没有ORDER BY dataQuery = fmt.Sprintf(` SELECT * FROM ( SELECT t.*, ROWNUM rn FROM %s t %s AND ROWNUM <= %d ) WHERE rn > %d`, fullTableName, whereClause, offset+params.PageSize, offset) } else { // 有WHERE条件和ORDER BY dataQuery = fmt.Sprintf(` SELECT * FROM ( SELECT inner.*, ROWNUM rn FROM ( SELECT * FROM %s %s %s ) inner WHERE ROWNUM <= %d ) WHERE rn > %d`, fullTableName, whereClause, orderByClause, offset+params.PageSize, offset) } } // 执行数据查询 dataResults, err := dbFactory.QuerySliceMap(dataQuery) if err != nil { return nil, fmt.Errorf("查询表数据失败: %v", err) } // 移除Oracle分页添加的rn字段 for i := range dataResults { delete(dataResults[i], "rn") } // 检查是否有更多数据 hasMore := (int64(offset+params.PageSize) < totalCount) 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, "full_table_name": fullTableName, "page": params.Page, "page_size": params.PageSize, "total_count": totalCount, "total_pages": totalPages, "where_clause": params.WhereClause, "order_by": params.OrderBy, "data": dataResults, "data_count": len(dataResults), "has_more": hasMore, "timestamp": time.Now().Format(time.RFC3339), "note": "数据获取限制:最多返回10条记录", }, nil }, ) }