【REST2SQL】02 GO连接Oracle数据库

【REST2SQL】01RDB关系型数据库REST初设计

Oracle数据库我用的最多,先研究Oracle,Go连接Oracle并实现REST和SQL服务。

1 Oracle数据库的安装

我这里安装使用的是Oracle 11g , 安装过程省略5217字。

2 安装Go-ora依赖

复制代码
 go get github.com/sijms/go-ora/v2 

安装成功后在GOPATH目录可见:

3 创建一个Gooracle控制台程序测试

全部代码如下 :

复制代码
// gooracle project main.go
package main

import (
	"database/sql/driver"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"os"

	go_ora "github.com/sijms/go-ora/v2" // 1 go get github.com/sijms/go-ora/v2
)

// Oracle连接字符串
const connStr string = "oracle://blma:5217@127.0.0.1:1521/CQYH"

func main() {
	var (
		sqls   string //sql语句
		result string //sql执行后返回的结果
	)

	// select查询数据
	sqls = "select sysdate from dual"
	result = selectData(sqls)
	fmt.Println(result)

	// delete 删除数据
	sqls = "delete from atop where p_id = -5"
	result = deleteData(sqls)
	fmt.Println(result)

	// update 更新数据
	sqls = "update atop set f_dm = '005217' where p_id = -5217"
	result = updateData(sqls)
	fmt.Println(result)

	// insert 插入一行数据
	sqls = "insert into atop (p_id) values (FLOOR(DBMS_RANDOM.value(0, 100)))"
	result = insertData(sqls)
	fmt.Println(result)
}

// 连接Oracle数据库
func connDB(connStr string) *go_ora.Connection {
	//创建连接
	DB, err := go_ora.NewConnection(connStr)
	dieOnError("Can't open the driver:", err)
	//打开连接
	err = DB.Open()
	dieOnError("Can't open the connection:", err)
	return DB
}

// delete
func deleteData(deleteSql string) string {
	result, _ := execSQL(deleteSql)
	rows, err := result.RowsAffected()
	dieOnError("Can't delete", err)
	ret := map[string]int{
		"Delete rowsAffected": int(rows),
	}
	jsonBytes, err := json.Marshal(ret)
	dieOnError("map 转 json失败:", err)
	return string(jsonBytes)
}

// update
func updateData(updateSql string) string {
	result, _ := execSQL(updateSql)
	rows, err := result.RowsAffected()
	dieOnError("Can't update", err)
	ret := map[string]int{
		"Update rowsAffected": int(rows),
	}
	jsonBytes, err := json.Marshal(ret)
	dieOnError("map 转 json失败:", err)
	return string(jsonBytes)
}

// insert
func insertData(insertSql string) string {
	result, _ := execSQL(insertSql)
	rows, err := result.RowsAffected()
	dieOnError("Can't insert", err)
	ret := map[string]int{
		"Insert rowsAffected": int(rows),
	}
	jsonBytes, err := json.Marshal(ret)
	dieOnError("map 转 json失败:", err)
	return string(jsonBytes)
}

// 执行SQL, execute stmt (INSERT, UPDATE, DELETE, DML, PLSQL) and return driver.Result object
func execSQL(sqls string) (result driver.Result, err error) {
	//连接数据库
	DB := connDB(connStr)
	//延迟关闭连接
	defer DB.Close()

	//准备sql语句
	stmt := go_ora.NewStmt(sqls, DB)
	//延迟关闭SQL
	defer stmt.Close()

	//执行SQL, execute stmt (INSERT, UPDATE, DELETE, DML, PLSQL) and return driver.Result object
	result, err = stmt.Exec(nil)
	dieOnError("Can't execSql() ", err)

	return result, err
}

// select查询,结果为json
func selectData(sqls string) string {
	//连接数据库
	DB := connDB(connStr)
	//延迟关闭连接
	defer DB.Close()

	//准备sql语句
	stmt := go_ora.NewStmt(sqls, DB)
	//延迟关闭SQL
	defer stmt.Close()

	rows, err := stmt.Query(nil)
	dieOnError("Can't query", err)

	defer rows.Close()

	//fmt.Println(rows)

	columns := rows.Columns()
	//fmt.Println("columns:", columns)
	values := make([]driver.Value, len(columns))
	var dataset []map[string]interface{} //元素为map的切片
	//Header(columns)
	for {
		err = rows.Next(values)
		if err != nil {
			break
		}
		//fmt.Println("values:", values)
		row1 := Record(columns, values)
		dataset = append(dataset, row1)

	}
	if err != io.EOF {
		dieOnError("Can't Next", err)
	}

	//切片转json
	jsonBytes, err := json.Marshal(dataset)
	dieOnError("slice 转 json失败:", err)
	//fmt.Println(string(jsonBytes))
	return string(jsonBytes)
}

// 发生错误退出1
func dieOnError(msg string, err error) {
	if err != nil {
		//fmt.Println(msg, err)
		log.Fatal(msg, err)
		os.Exit(1)
	}
}

// func Header(columns []string) {

// }

// 一行记录加入 map
func Record(columns []string, values []driver.Value) map[string]interface{} {
	mc := make(map[string]interface{}) //一行记录信息放入 map
	for i, c := range values {
		//fmt.Printf("\"%s\":%v,", columns[i], c)
		mc[columns[i]] = c
	}
	//fmt.Println(mc)

	return mc //返回一行记录的信息map
}

// func returnErr(err error) error {
// 	if err != nil {
// 		return err
// 	}
// 	return nil
// }

// // 7调用存储过程
// func callStoredProcedure() error {
// 	var (
// 		id  int
// 		msg string = strings.Repeat(" ", 2000) //先赋值内容
// 	)
// 	//执行存储过程,
// 	_, err := db.Exec(`BEGIN ora_test2_pro(:1, :2 ); END;`,
// 		id,
// 		sql.Out{Dest: &msg},
// 	)
// 	if err != nil {
// 		return err
// 	}
// 	//输出结果
// 	fmt.Println(msg)
// 	return nil
// }

// // 8.调用函数
// func callFunction() error {
// 	var (
// 		id  int
// 		msg string = strings.Repeat(" ", 2000) //先赋值内容
// 	)
// 	//执行存储过程,
// 	_, err := db.Exec(`BEGIN :1 := ora_test2_func(:2 ); END;`,
// 		sql.Out{Dest: &msg},
// 		id,
// 	)
// 	if err != nil {
// 		return err
// 	}
// 	//输出结果
// 	fmt.Println(msg)
// 	return nil
// }

运行输出结果如下:

{"SYSDATE":"2024-01-03T15:46:39+08:00"}

{"Delete rowsAffected":0}

{"Update rowsAffected":1}

{"Insert rowsAffected":1}

相关推荐
jiayou6421 小时前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤2 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区3 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1773 天前
《从零搭建NestJS项目》
数据库·typescript
花酒锄作田3 天前
Gin 框架中的规范响应格式设计与实现
golang·gin
加号34 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏4 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐4 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再4 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
tryCbest4 天前
数据库SQL学习
数据库·sql