Golang MySQL存储过程的使用

原创 2016年06月02日 11:44:35

Golang MySQL存储过程的使用

使用前阅读

ref-1:问题来源 [支付系统数据库设计的关键问题 ]
ref-2:
[Golang 用go-sql-driver 调用MySQL存储过程时的问题排查]

编辑文件src/github.com/go-sql-driver/mysql/packets.go文件,在函数writeAuthPacket(cipher []byte) (大约在210行)的客户端标志位处添加下面两个标志:

func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
        // Adjust client flags based on server support                                                                                     
        clientFlags := clientProtocol41 |
                clientSecureConn |
                clientLongPassword |
                clientTransactions |
                clientLocalFiles |
                **clientMultiStatements |    // 添加这行
                clientMultiResults |**       //再添加这行
                mc.flags&clientLongFlag

        if mc.cfg.clientFoundRows {
                clientFlags |= clientFoundRows
        }

一、MySQL创建存储过程

-- 单行执行以下语句
SET NAMES utf8;
-- dsp_settle数据库
USE dsp_settle;

DROP PROCEDURE IF EXISTS settle_balance_deduction;

-- [1]设置分隔符为//
DELIMITER //

--[2] 执行source /path/to/procedure.sql;  !!! ERROR
--[2]copy /PATH/TO/procedure.sql to console and enter

--[3]还原分隔符
DELIMITER ;


--[4]调用示例
call settle_balance_deduction(5372539, 1234, 100, @out_status);
select @out_status;

-- 其他常用操作
-- 调研存储过程
call procedure_name(parameters);

-- 查询存储过程
SHOW PROCEDURE STATUS;

-- 显示一个存储过程详情
SHOW CREATE PROCEDURE procedure_name;

-- 删除存储过程
DROP PROCEDURE procedure_name;

存储过程代码

-- 创建存储过程
CREATE PROCEDURE settle_balance_deduction (in_userID bigint, in_planID INT, in_money INT, OUT out_status INT )
BEGIN
  -- 变量 用户实际余额
  DECLARE account_balance INT;

  START TRANSACTION;
  SELECT balance INTO account_balance FROM dsp_settle.user_balance WHERE userId = in_userID AND status = 0 AND isDelete = 0 FOR UPDATE;

  IF account_balance >= in_money THEN
    -- 扣费操作
    UPDATE user_balance SET balance = balance - in_money, opUserId = 1001 WHERE userId = in_userID;

    -- 扣费记录
    INSERT INTO dsp_settle.charge_record(userId, planId, charge, opUserId, addTime) VALUES (in_userID, in_planID, in_money, 1001, NOW());

    -- 提交事务处理
    COMMIT;

    -- 返回结果状态1
    SET out_status = 1;
  ELSE
    -- 余额小于扣费额,不操作
    ROLLBACK;

    -- 返回结果状态0
    SET out_status = 0;
  END IF;
END //

Go调用存储过程代码,亲测可用

package balance

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "strconv"
    "fmt"
)

const (
    //DSN = "root:tongzhen@tcp(127.0.0.1:3306)"
    DSN = "root:123456@tcp(10.48.23.51:8086)"
    DB_DSP = "dsp"
    DB_SETTLE = "dsp_settle"
)

//扣费结算
func Settle(userID int, planID int, charge int)  int{
    db, err := sql.Open("mysql", DSN + "/" + DB_SETTLE)
    if err != nil {
        panic(err.Error())
    }
    defer db.Close()

    handle, err := db.Prepare("CALL dsp_settle.settle_balance_deduction(?, ?, ?, @out_status)")
    if err != nil {
        panic(err.Error())
    }
    defer handle.Close()

    //call procedure
    var result sql.Result
    result, err = handle.Exec(userID, planID, charge)
    if err != nil {
        panic(err.Error())
    }
    fmt.Println(result)

    var sql string = "SELECT @out_status as ret_status"
    selectInstance, err := db.Prepare(sql)
    if err != nil {
        panic(err.Error())
    }
    defer selectInstance.Close()

    var ret_status int
    err = selectInstance.QueryRow().Scan(&ret_status)
    if err != nil {
        panic(err.Error())
    }
    fmt.Println(ret_status)
    return ret_status
}

todo 完善该wiki

版权声明:本文为博主@乐不思蜀Tone 原创文章,未经博主允许不得转载。

golang调用sql server proc

许久没写博客,近来真有点郁闷,首先自己水平有限,在成为大牛的路上努力挣扎中,狰狞地挣扎,其次是不满某些人的某些态度,我觉得态度是很重要的,好,吐槽完毕。 由于项目需要,需要用到sql server。...

golang 线程与通道

golang的线程和通道

mysql procedure 存储过程

1. 存储过程简介 我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库...

golang连接mysql操作示例增删改查

http://www.01happy.com/golang-mysql-demo/ 下载驱动 sudo go get github.com/go-sql-driver/mysql 如...

使用Navicat for MySQL创建存储过程

1.打开navicat选择要创建存储过程的数据库,右击函数,创建。 2.添加所要输入的参数,选择模式和类型(!这里并没有默认提供大小)。 3.输入存储过程的定义语句。 4.保存,输入存储...
  • Forlogen
  • Forlogen
  • 2016年02月01日 14:42
  • 14445

MySQL最大连接数设置

在使用MySQL数据库的时候,经常会遇到这么一个问题,就是“Can not connect to MySQL server. Too many connections”-mysql 1040错误,这是...
  • WOOSHN
  • WOOSHN
  • 2012年10月14日 16:17
  • 106275

MySQL 存储过程与游标的混合使用

  • 2013年10月23日 18:43
  • 44KB
  • 下载

Mysql使用大全-从基础到存储过程

  • 2013年11月24日 14:52
  • 78KB
  • 下载

MySQL 使用存储过程实现留存率

DELIMITER // USE `resourcemanage-dev`// DROP PROCEDURE IF EXISTS `stat_remain_player`// CREATE...

mysql数据库上使用定时器定时执行存储过程建表(月表)

最近有个需求,在mysql数据库中每个月建自动一个表,把该月的数据存储到该月对应的表中。一、创建存储过程期望表名: login_history_2017_07(login_history_YYYY_...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Golang MySQL存储过程的使用
举报原因:
原因补充:

(最多只允许输入30个字)