zoukankan      html  css  js  c++  java
  • Node.js调用mysql的存储过程

    例子仅在windows下测试通过,没有放在linux下测试。如有问题,可以电邮给我~

    1、安装node.js、mysql,此处略(自行搜索吧)…;

    2、创建一个名为test的数据库,然后建一张名为user_info的表(仅供测试)…

    这里假定mysql使用的用户名为root,密码为123456

    相应的mysql如下:

    /**
    * 创建名为test的数据库
    */
    DROP DATABASE IF EXISTS test;
    CREATE DATABASE test;
    USE test;
     

    /**
    * 创建user_info表
    */
    DROP TABLE IF EXISTS `user_info`;

    CREATE TABLE `user_info` (
    `userId` int(10) NOT NULL AUTO_INCREMENT,
    `userName` varchar(20) DEFAULT NULL,
    PRIMARY KEY (`userId`)
    ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

    /**
    * 插入三条记录
    */
    INSERT INTO user_info VALUES (NULL, '张一'), (NULL, '张二'), (NULL, '张三');


    3、创建存储过程(写的很冗余,故意的… 正好学习一下语法>_<);

    DELIMITER $$
    DROP PROCEDURE IF EXISTS `test`.`proc_simple`$$
    CREATE PROCEDURE proc_simple(IN uid INT(10), OUT uName VARCHAR(2), OUT totalCount INT)
    BEGIN

    DECLARE str_name VARCHAR(20);

    SET @str_name = '';
    SET totalCount = 0;
    SELECT COUNT(1),userName INTO totalCount,@str_name FROM user_info WHERE userId = uid;
    SET uName = @str_name;
    SELECT uName, totalCount;

    END$$
    DELIMITER ;
     
    4、写程序进行调用(假定存为名为sql.js的文件);
    /**
    * Created with JetBrains WebStorm.
    * User: Meteoric_cry
    * Date: 12-12-28
    * Time: 上午00:18
    * To change this template use File | Settings | File Templates.
    */
    var mysql = require('mysql');

    var connection = mysql.createConnection({
    host : 'localhost',
    port : 3306,
    user : 'root',
    password : '123456',
    database : 'test',
    charset : 'UTF8_GENERAL_CI',
    debug : false
    });

    connection.connect();

    connection.query('CALL proc_simple(1, @a, @b);', function(err, rows, fields) {
    if (err) {
    throw err;
    }

    var results = rows[0];
    var row = results[0];
    console.log("userName:",row.uName, "  count:", row.totalCount);
    });

    connection.end();
     
    5、运行示例程序;
     

    本文参考链接:

    mysql 存储程序和函数

    mysql(procedure)

    node-mysql

    /***************************************************************/

    如果对mysql的行记录锁定、表锁定,有兴趣想了解更多,可以继续阅读(有空准备写个复杂点的应用,所以需要了解一些这方面的知识,下面的文字摘抄自SELECT FOR UPDATE):

    举个例子: 假设商品表单products 内有一个存放商品数量的quantity ,在订单成立之前必须先确定quantity 商品数量是否足够(quantity>0) ,然后才把数量更新为1。
    不安全的做法:
    SELECT quantity FROM products WHERE id=3;UPDATE products SET quantity = 1 WHERE id=3;
    为什么不安全呢?
    少量的状况下或许不会有问题,但是大量的数据存取「铁定」会出问题。
    如果我们需要在quantity>0 的情况下才能扣库存,假设程序在第一行SELECT 读到的quantity 是2 ,看起来数字没有错,但是当MySQL 正准备要UPDATE 的时候,可能已经有人把库存扣成0 了,但是程序却浑然不知,将错就错的UPDATE 下去了。
    因此必须透过的事务机制来确保读取及提交的数据都是正确的。


    于是我们在MySQL 就可以这样测试: (注1)
    SET AUTOCOMMIT=0;BEGIN WORK;SELECT quantity FROM products WHERE id=3 FOR UPDATE;

    此时products 数据中id=3 的数据被锁住(注3),其它事务必须等待此次事务提交后才能执行SELECT * FROM products WHERE id=3 FOR UPDATE (注2)如此可以确保quantity 在别的事务读到的数字是正确的。

    UPDATE products SET quantity = '1' WHERE id=3 ;COMMIT WORK;

    提交(Commit)写入数据库,products 解锁。


    注1: BEGIN/COMMIT 为事务的起始及结束点,可使用二个以上的MySQL Command 视窗来交互观察锁定的状况。
    注2: 在事务进行当中,只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据时会等待其它事务结束后才执行,一般SELECT ... 则不受此影响。
    注3: 由于InnoDB 预设为Row-level Lock,数据列的锁定可参考这篇。
    注4: InnoDB 表单尽量不要使用LOCK TABLES 指令,若情非得已要使用,请先看官方对于InnoDB 使用LOCK TABLES 的说明,以免造成系统经常发生死锁。

    MySQL SELECT ... FOR UPDATE 的Row Lock 与Table Lock
    上面介绍过SELECT ... FOR UPDATE 的用法,不过锁定(Lock)的数据是判别就得要注意一下了。由于InnoDB 预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)。
    举个例子:
    假设有个表单products ,里面有id 跟name 二个栏位,id 是主键。
    例1: (明确指定主键,并且有此数据,row lock)
    SELECT * FROM products WHERE id='3' FOR UPDATE;
    例2: (明确指定主键,若查无此数据,无lock)
    SELECT * FROM products WHERE id='-1' FOR UPDATE;
    例2: (无主键,table lock)
    SELECT * FROM products WHERE name='Mouse' FOR UPDATE;
    例3: (主键不明确,table lock)
    SELECT * FROM products WHERE id<>'3' FOR UPDATE;
    例4: (主键不明确,table lock)
    SELECT * FROM products WHERE id LIKE '3' FOR UPDATE;
    注1: FOR UPDATE 仅适用于InnoDB,且必须在事务区块(BEGIN/COMMIT)中才能生效。
    注2: 要测试锁定的状况,可以利用MySQL 的Command Mode ,开二个视窗来做测试。

  • 相关阅读:
    Lambda表达式、依赖倒置
    ASP.NET vNext 概述
    Uname
    RHEL4 i386下安装rdesktop【原创】
    Taxonomy of class loader problems encountered when using Jakarta Commons Logging(转)
    How to decompile class file in Java and Eclipse
    先有的资源,能看的速度看,不能看的,抽时间看。说不定那天就真的打不开了(转)
    Google App Engine 学习和实践
    【VBA研究】VBA通过HTTP协议实现邮件轨迹跟踪查询
    js正則表達式语法
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/2836666.html
Copyright © 2011-2022 走看看