Ei kuvausta
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

get_oracle_columns.go 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. package dbs
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strings"
  6. "time"
  7. "git.x2erp.com/qdy/go-svc-mcp/internal/mcp"
  8. )
  9. func init() {
  10. mcp.Register("get_oracle_columns", "根据表名称获取Oracle表的所有字段相关信息",
  11. map[string]interface{}{
  12. "type": "object",
  13. "properties": map[string]interface{}{
  14. "table_name": map[string]interface{}{
  15. "type": "string",
  16. "description": "表名称(支持大小写敏感)",
  17. },
  18. "schema": map[string]interface{}{
  19. "type": "string",
  20. "description": "模式名称(默认为当前用户)",
  21. "default": "",
  22. },
  23. "include_comments": map[string]interface{}{
  24. "type": "boolean",
  25. "description": "是否包含字段注释",
  26. "default": true,
  27. },
  28. "database_key": map[string]interface{}{
  29. "type": "string",
  30. "description": "数据库配置键名(如:business),可选,默认使用主数据库",
  31. "enum": []string{"warehouse", "business"},
  32. "default": "warehouse",
  33. },
  34. },
  35. "required": []string{"table_name"},
  36. },
  37. func(input json.RawMessage, deps *mcp.ToolDependencies) (interface{}, error) {
  38. var params struct {
  39. TableName string `json:"table_name"`
  40. Schema string `json:"schema"`
  41. IncludeComments bool `json:"include_comments"`
  42. DatabaseKey string `json:"database_key"`
  43. }
  44. if len(input) > 0 {
  45. if err := json.Unmarshal(input, &params); err != nil {
  46. return nil, err
  47. }
  48. }
  49. // 获取数据库工厂
  50. dbFactory, err := GetDBFactory(params.DatabaseKey, deps)
  51. if err != nil {
  52. return nil, err
  53. }
  54. // 获取数据库类型,确保是Oracle
  55. dbType := dbFactory.GetDBType()
  56. if dbType != "oracle" {
  57. return nil, fmt.Errorf("当前数据库类型为 %s,此工具仅支持Oracle数据库", dbType)
  58. }
  59. // 清理表名和模式名
  60. tableName := strings.TrimSpace(params.TableName)
  61. schema := strings.TrimSpace(params.Schema)
  62. if tableName == "" {
  63. return nil, fmt.Errorf("表名称不能为空")
  64. }
  65. // 构建查询SQL
  66. var query string
  67. if schema == "" {
  68. // 查询当前用户下的表字段信息
  69. if params.IncludeComments {
  70. query = `
  71. SELECT
  72. c.column_id,
  73. c.column_name,
  74. c.data_type,
  75. c.data_length,
  76. c.data_precision,
  77. c.data_scale,
  78. c.nullable,
  79. c.data_default as column_default,
  80. cc.comments as column_comment
  81. FROM user_tab_columns c
  82. LEFT JOIN user_col_comments cc ON c.table_name = cc.table_name AND c.column_name = cc.column_name
  83. WHERE c.table_name = UPPER(:1)
  84. ORDER BY c.column_id`
  85. } else {
  86. query = `
  87. SELECT
  88. column_id,
  89. column_name,
  90. data_type,
  91. data_length,
  92. data_precision,
  93. data_scale,
  94. nullable,
  95. data_default as column_default
  96. FROM user_tab_columns
  97. WHERE table_name = UPPER(:1)
  98. ORDER BY column_id`
  99. }
  100. } else {
  101. // 查询指定模式下的表字段信息
  102. if params.IncludeComments {
  103. query = `
  104. SELECT
  105. c.column_id,
  106. c.column_name,
  107. c.data_type,
  108. c.data_length,
  109. c.data_precision,
  110. c.data_scale,
  111. c.nullable,
  112. c.data_default as column_default,
  113. cc.comments as column_comment
  114. FROM all_tab_columns c
  115. 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
  116. WHERE c.table_name = UPPER(:1)
  117. AND c.owner = UPPER(:2)
  118. ORDER BY c.column_id`
  119. } else {
  120. query = `
  121. SELECT
  122. column_id,
  123. column_name,
  124. data_type,
  125. data_length,
  126. data_precision,
  127. data_scale,
  128. nullable,
  129. data_default as column_default
  130. FROM all_tab_columns
  131. WHERE table_name = UPPER(:1)
  132. AND owner = UPPER(:2)
  133. ORDER BY column_id`
  134. }
  135. }
  136. // 执行查询
  137. var results []map[string]interface{}
  138. if schema == "" {
  139. results, err = dbFactory.QuerySliceMapWithParams(query, tableName)
  140. } else {
  141. results, err = dbFactory.QuerySliceMapWithParams(query, tableName, schema)
  142. }
  143. if err != nil {
  144. return nil, fmt.Errorf("查询表字段信息失败: %v", err)
  145. }
  146. if len(results) == 0 {
  147. // 尝试查询表是否存在
  148. var tableExistsQuery string
  149. if schema == "" {
  150. tableExistsQuery = `SELECT COUNT(*) as table_count FROM user_tables WHERE table_name = UPPER(:1)`
  151. } else {
  152. tableExistsQuery = `SELECT COUNT(*) as table_count FROM all_tables WHERE table_name = UPPER(:1) AND owner = UPPER(:2)`
  153. }
  154. var tableCheckResults []map[string]interface{}
  155. if schema == "" {
  156. tableCheckResults, err = dbFactory.QuerySliceMapWithParams(tableExistsQuery, tableName)
  157. } else {
  158. tableCheckResults, err = dbFactory.QuerySliceMapWithParams(tableExistsQuery, tableName, schema)
  159. }
  160. if err == nil && len(tableCheckResults) > 0 {
  161. if count, ok := tableCheckResults[0]["table_count"].(int64); ok && count == 0 {
  162. return nil, fmt.Errorf("表 '%s' 不存在", tableName)
  163. }
  164. }
  165. return nil, fmt.Errorf("表 '%s' 存在但没有字段信息或表为空", tableName)
  166. }
  167. // 处理字段信息,确保null值转换为空字符串
  168. for i := range results {
  169. // 处理NULLABLE字段
  170. if nullable, ok := results[i]["nullable"].(string); ok {
  171. results[i]["is_nullable"] = nullable == "Y"
  172. delete(results[i], "nullable")
  173. }
  174. // 处理注释字段
  175. if params.IncludeComments {
  176. if comment, ok := results[i]["column_comment"]; ok && comment == nil {
  177. results[i]["column_comment"] = ""
  178. }
  179. }
  180. // 处理默认值
  181. if defaultValue, ok := results[i]["column_default"]; ok && defaultValue == nil {
  182. results[i]["column_default"] = ""
  183. }
  184. // 构建完整的数据类型
  185. dataType := ""
  186. if dt, ok := results[i]["data_type"].(string); ok {
  187. dataType = dt
  188. if precision, ok := results[i]["data_precision"].(int64); ok && precision > 0 {
  189. if scale, ok := results[i]["data_scale"].(int64); ok && scale > 0 {
  190. dataType = fmt.Sprintf("%s(%d,%d)", dt, precision, scale)
  191. } else {
  192. dataType = fmt.Sprintf("%s(%d)", dt, precision)
  193. }
  194. } else if length, ok := results[i]["data_length"].(int64); ok && length > 0 {
  195. // 对于VARCHAR2/CHAR等类型
  196. dataType = fmt.Sprintf("%s(%d)", dt, length)
  197. }
  198. results[i]["full_data_type"] = dataType
  199. }
  200. }
  201. // 获取表注释
  202. var tableComment string
  203. if schema == "" {
  204. tableCommentQuery := `SELECT comments FROM user_tab_comments WHERE table_name = UPPER(:1)`
  205. commentResults, err := dbFactory.QuerySliceMapWithParams(tableCommentQuery, tableName)
  206. if err == nil && len(commentResults) > 0 {
  207. if comment, ok := commentResults[0]["comments"].(string); ok {
  208. tableComment = comment
  209. }
  210. }
  211. } else {
  212. tableCommentQuery := `SELECT comments FROM all_tab_comments WHERE table_name = UPPER(:1) AND owner = UPPER(:2)`
  213. commentResults, err := dbFactory.QuerySliceMapWithParams(tableCommentQuery, tableName, schema)
  214. if err == nil && len(commentResults) > 0 {
  215. if comment, ok := commentResults[0]["comments"].(string); ok {
  216. tableComment = comment
  217. }
  218. }
  219. }
  220. return map[string]interface{}{
  221. "tenant_id": deps.ReqCtx.TenantID,
  222. "user_id": deps.ReqCtx.UserID,
  223. "database_type": dbType,
  224. "database_name": dbFactory.GetDatabaseName(),
  225. "schema": schema,
  226. "table_name": tableName,
  227. "table_comment": tableComment,
  228. "include_comments": params.IncludeComments,
  229. "columns": results,
  230. "total_columns": len(results),
  231. "timestamp": time.Now().Format(time.RFC3339),
  232. }, nil
  233. },
  234. )
  235. }