4. 存储过程中有个DEFINER
(1) DEFINER的意思是“定义者”,也就是指明此存储过程有哪个用户定义的,它跟存储过程的使用权限无关;
可以说,存储和过程是没有使用限制的,任何人都可以使用存储过程,那么为什么还要加上DEFINER指定存储过
程的定义者呢,因为,存储过程虽然不限制任何人使用,但是它本身的行为必须受到权限限制,也就是存储过程
本身内部具备哪些对数据库的访问权限,而这访问权限便是DEFINER用户对数据库的访问权限。
(2) DEFINER被定义为一个普通的username@hostname用户就不必说了,如果定义为root@%,有什么特别的吗?没
有。只不过数据库中要存在root@%用户,否则创建的时候没事,调用的时候就提示root@% is not registered,
也就是用户不存在。
(3) DEFINER也可以省略掉,这样存储过程默认的定义者是root@localhost,而一般数据库在安装的时候都会有
一个root@localhost用户,所以,该存储过程也能正常在不同的机器上被使用。
5. 既然上述存储过程任何人都以访问,那么它本身运行时的访问权限怎么限制呢。可以通过SQL SECURITY
INVOKER ,也就是,其本身的访问权限由调用者权限设置。
6.命令分隔符DELIMITER
MySQL默认是以分号作为两个命令的分割点的。但有些命令块中包含分号,比如存储过程或触发器的定义中。为了使MySQL不把命令块中的分号误认做命令的分割点,需要在执行这种命令块前临时改一下命令分隔符。尤其注意,SQLYog里面写存储过程的时候,必须自行定义命令分隔符。
下面的过程是一个用户扫描店东二维码的时候,由于错误导致返款未达店东账号,需要返款给店东
这里面主要注意的是,局部变量的定义,进参的定义,及concat连接多个字符串报类型不一致的处理,还有过程中 ,insert into中文导致乱码问题的解决
/*
created by shitian
data:2017-12-20
call sample:ChongzhengConsumerScanStores(15998761087,15953440858,9404917904562053123606861003);
出入参数依次为,店东手机号,消费者手机号,商户单号(transaction_no)
*/
DELIMITER $
drop PROCEDURE if EXISTS ChongzhengConsumerScanStores;
CREATE PROCEDURE ChongzhengConsumerScanStores(IN p_stores_mobile varchar(100),IN p_consumer_mobile varchar(100),IN p_transaction_no varchar(100))
BEGIN
DECLARE stores_member_id VARCHAR(100) ;
DECLARE consumer_member_id VARCHAR(100) ;
/* 使用 charcter set utf8 避免乱码*/
DECLARE string_json VARCHAR(300)character set utf8 ;
DECLARE amt VARCHAR(10) ;
DECLARE pre_balance VARCHAR(20);
DECLARE remark VARCHAR(200) character set utf8;
DECLARE remark_json VARCHAR(300) character set utf8;
select member_id into stores_member_id from mddb.md_user_member where member_type_key='stores' and user_id in (
select user_id from iddb.id_user where mobile= p_stores_mobile
);
select member_id into consumer_member_id from mddb.md_user_member where member_type_key='consumer' and user_id in (
select user_id from iddb.id_user where mobile= p_consumer_mobile
);
select amount INTO amt from fddb.fd_transactions_result where transaction_no=p_transaction_no;
select cash_balance into pre_balance from fddb.fd_member_asset where member_id=stores_member_id;
/*concat 中如不强制转换类型则提示类型不一致*/
SELECT
concat(
'{"seller_id":',
'"' ,convert(stores_member_id,char),
'"',
',',
'\"detail\":\"扫码支付(交易冲正,系统退款)\",\"amount\":',
'"' ,convert(amt,char),
'"',
',',
'\"data_source\":\"SJLY_01\",\"buyer_id\":',
'"' ,convert(consumer_member_id,char),
'"',
',',
'\"payment_way_key\":\"ZFFS_05\"}'
) into string_json
from dual;
select CONCAT('消费者端App|余额支付|零钱|',convert(amt,char)) into remark from dual;
SELECT
CONCAT(
'{\"business_type_key\":\"JYLX_03\",\"detail\":\"扫码支付(交易冲正,系统退款)\",\"payment_way_key\":\"ZFFS_05\",\"transaction_member_contact\":',
'"',
convert(p_consumer_mobile,char),
'"',
',',
'\"transaction_member_id\":',
'"' ,convert(consumer_member_id,char),
'"',
',',
'\"transaction_member_name\":',
'"' ,convert(p_consumer_mobile,char),
'"',
',',
'\"transaction_member_type_key\":\"consumer\",\"transaction_no\":',
'"' ,convert(p_transaction_no,char),
'"',
'}'
) INTO remark_json from dual;
UPDATE `fddb`.`fd_transactions_result`
SET
out_trade_body = string_json,
`buyer_id` = consumer_member_id,
`buyer_contact` = p_consumer_mobile ,
`detail` = '扫码支付(交易冲正,系统退款)',
`seller_id` = stores_member_id,
`transaction_status` = 'completed'
WHERE transaction_no= p_transaction_no;
/*补齐店东分账记录*/
INSERT INTO fddb.fd_cash_daily_account_store(
`daily_account_id`,
`member_id`,
`transaction_member_type`,
`transaction_member_id`,
`transaction_member_name`,
`transaction_member_contact`,
`transaction_no`,
`data_source`,
`business_type_key`,
`payment_way_key`,
`transaction_date`,
`detail`,
`pre_balance`,
`amount`,
`balance`,
`currency_code`,
`out_trade_no`,
`account_date`,
`booking_mark`,
`created_date`,
`remark`
)
VALUES
(
MD5(UUID()),
stores_member_id,
'consumer',
consumer_member_id,
'',
p_consumer_mobile,
p_transaction_no,
'SJLY_01',
'JYLX_03',
'ZFFS_05',
now(),
'扫码支付',
pre_balance,
amt,
pre_balance+amt,
'CNY',
NULL,
now(),
'income',
now(),
remark
);
/*现金交易日志补齐*/
INSERT INTO `fddb`.`fd_member_cash_log` (
`log_id`,
`member_type_key`,
`member_id`,
`category`,
`pre_balance`,
`amount`,
`balance`,
`tracked_date`,
`remark`
)
VALUES
(
md5(UUID()),
'stores',
stores_member_id,
'income',
pre_balance,
amt,
pre_balance+amt,
now(),
remark_json
);
/*给店东加余额*/
UPDATE fddb.fd_member_asset
set cash_balance = cash_balance + amt
WHERE
member_id=stores_member_id
;
END
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!