1.声明性SQL语句。 1. 触发器,2. 其他存储过程以及3. Java,Python,php等应用程序可以调用存储过程。 2.mysql主要高级的功能:存储过程,存储函数,触发器和事件 3.优点是: 减轻web服务器的压力, 将些业务转移到sql 服务器去 4.-------------------------------------- 5.创建一个名字叫做:GetAllProducts()的存储过程 DELIMITER // CREATE PROCEDURE GetAllProducts() BEGIN SELECT * FROM products; END //DELIMITER ; 6.调用存储过程 CALL STORED_PROCEDURE_NAME(); 7.-------------------------------------- 声明变量:DECLARE variable_name datatype(size) DEFAULT default_value; set分配变量:DECLARE total_count INT DEFAULT 0;SET total_count = 10; Set Into 分配变量:DECLARE total_products INT DEFAULT 0 SELECT COUNT(*) INTO total_productsFROM products 8.作用域问题: 一般作用域是 begin 到end , 然后加上@ 是属于会话变量,在其他存储过程也可以使用 定义参数:MODE param_name param_type(param_size) ?根据存储过程中参数的目的,MODE可以是IN,OUT或INOUT。 In的实例:USE `yiibaidb`;DROP procedure IF EXISTS `GetOfficeByCountry`; DELIMITER $$USE `yiibaidb`$$CREATE PROCEDURE GetOfficeByCountry(IN countryName VARCHAR(255)) BEGIN SELECT * FROM offices WHERE country = countryName; END$$ DELIMITER ; CALL GetOfficeByCountry(‘USA‘); CALL GetOfficeByCountry(‘USA‘); Out的实例:USE `yiibaidb`;DROP procedure IF EXISTS `CountOrderByStatus`; DELIMITER $$CREATE PROCEDURE CountOrderByStatus( IN orderStatus VARCHAR(25), OUT total INT)BEGIN SELECT count(orderNumber) INTO total FROM orders WHERE status = orderStatus;END$$DELIMITER ; CALL CountOrderByStatus(‘Shipped‘,@total); SELECT @total; #赋值给全局的变量 Inout的实例DELIMITER $$CREATE PROCEDURE set_counter(INOUT count INT(4),IN inc INT(4))BEGIN SET count = count + inc;END$$DELIMITER ; #关于全局的变量值的处理 SET @counter = 1; CALL set_counter(@counter,1); -- 2 CALL set_counter(@counter,1); -- 3 CALL set_counter(@counter,5); -- 8 SELECT @counter; -- 8 9.关于 mybaties中调用存储过程的代码: <!-- 调用存储过程递归删除部门以及部门下的所有子部门 --> <delete id="deleteProcedureById" statementType="CALLABLE"> { call delete_department(#{id, mode=IN}) } </delete> 根据手册 可以查到, 别照抄老师代码:http://www.mybatis.org/mybatis-3/sqlmap-xml.html 10.返回多个值的存储过程示例 DELIMITER $$ CREATE PROCEDURE get_order_by_cust( IN cust_no INT, OUT shipped INT, OUT canceled INT, OUT resolved INT, OUT disputed INT)BEGIN -- shipped SELECT count(*) INTO shipped FROM orders WHERE customerNumber = cust_no AND status = ‘Shipped‘; -- canceled SELECT count(*) INTO canceled FROM orders WHERE customerNumber = cust_no AND status = ‘Canceled‘; -- resolved SELECT count(*) INTO resolved FROM orders WHERE customerNumber = cust_no AND status = ‘Resolved‘; -- disputed SELECT count(*) INTO disputed FROM orders WHERE customerNumber = cust_no AND status = ‘Disputed‘; END 11.条件语句 IF expression THEN statements;ELSE else-statements;END IF; 12.选择语句 CASE case_expression WHEN when_expression_1 THEN commands WHEN when_expression_2 THEN commands ... ELSE commandsEND CASE; 13.循环 WHILE语句的语法如下: WHILE expression DO statementsEND WHILE WHILE语句的语法如下: WHILE expression DO Statements END WHILE loop_label: LOOP IF x > 10 THEN LEAVE loop_label; END IF; 14.游标 存储函数和触发器中使用MySQL游标。 处理存储过程中的结果集,请使用游标。游标允许您迭代查询返回的一组行,并相应地处理每行。 MySQL游标为只读,不可滚动和敏感。 敏感:有两种游标:敏感游标和不敏感游标。敏感游标指向实际数据,不敏感游标使用数据的临时副本。 不可滚动:只能按照SELECT语句确定的顺序获取行,不可 跳转取,不可逆向取 声明游标: DECLARE cursor_name CURSOR FOR SELECT_statement; 游标声明必须在变量声明之后 OPEN cursor_name; FETCH cursor_name INTO variables list; CLOSE cursor_name; DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1; 15.显示存储过程的语句 根据数据库:SHOW PROCEDURE STATUS WHERE db = ‘yiibaidb‘; 根据存储过程的名字模糊查询:SHOW PROCEDURE STATUS WHERE name LIKE ‘%product%‘ 根据名字直接查询:SHOW CREATE PROCEDURE stored_procedure_name 16.声明处理程序(比如错误) DECLARE action HANDLER FOR condition_value statement; SQL 如果条件的值与condition_value匹配,则MySQL将执行statement,并根据该操作继续或退出当前的代码块。 操作(action)接受以下值之一: ?CONTINUE:继续执行封闭代码块(BEGIN ... END)。 ?EXIT:处理程序声明封闭代码块的执行终止。 condition_value指定一个特定条件或一类激活处理程序的条件。condition_value接受以下值之一: ?一个MySQL错误代码。 ?标准SQLSTATE值或者它可以是SQLWARNING,NOTFOUND或SQLEXCEPTION条件,这是SQLSTATE值类的简写。NOTFOUND条件用于游标或SELECT INTO variable_list语句。 ?与MySQL错误代码或SQLSTATE值相关联的命名条件。 例如:DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET has_error = 1; DECLARE EXIT HANDLER FOR SQLEXCEPTIONBEGINROLLBACK;SELECT ‘An error has occurred, operation rollbacked and the stored procedure was terminated‘;END; 17.Mysql 处理的优先级, 是错误代码最为具体, 所以错误代码优先级最高 18.声明命名错误的条件: DECLARE condition_name CONDITION FOR condition_value; DECLARE table_not_found CONDITION for 1051;DECLARE EXIT HANDLER FOR table_not_found SELECT ‘Please create table abc first‘;SELECT * FROM abc; 19.添加返回的错误信息,根据错误码 SIGNAL SQLSTATE ‘45000‘ SET MESSAGE_TEXT = ‘Order No not found in orders table‘; DECLARE division_by_zero CONDITION FOR SQLSTATE ‘22012‘; DECLARE CONTINUE HANDLER FOR division_by_zero RESIGNAL SET MESSAGE_TEXT = ‘Division by zero / Denominator cannot be zero‘; 20.存储函数 CREATE FUNCTION function_name(param1,param2,…) RETURNS datatype [NOT] DETERMINISTIC statements 21. 12
2018-01-15
------------------------------------------不能下载所以只能贴出来:
题目部分:
1. 利用存储过程求出,product的总数来
2. 将product中的商品数量放置到 变量 total_product中去
3. 根据Country查到office, 要求是输入的变量必须是countryName int
4. 过订单状态返回订单数量。参数分别为:in orderStatus varchar(255) ,out total int
5. 穿入一个参数inout类型 a, 还有一个int类型的参数 b, 存储过程a = a + b, 这样a既是输入也是输出参数
6. 输入4customerNumber ,和status ,来获取, 输入shipped canceled resolved disputed
7. 根据customerNumber获取creditlimit,然后据此进行判断是在哪个区间 10000 50000
8. 根据customerNumber 获取customerCountry, 然后据此进行判断举办活动的时间是几天
9. 将1到5 拼成字符串, while do end while , repeat until end repeat,
10. email_list,字符串放进去,利用游标和concat进行拼接得到varcahr类型
11. 创建一张表, 然后自己做实验, 如果出现重复出现的结果的时候可以报你插入的地方重复插入
#1. get allProduct DELIMITER $$ CREATE PROCEDURE GetAllProduck() BEGIN SELECT * FROM products; END $$ DELIMITER ; CALL GetAllProduck() #2. 将product中的商品数量放置到 变量 total_product中去 DELIMITER $$ CREATE PROCEDURE countProduct4() BEGIN DECLARE count_products INT DEFAULT 0; #set count_products = xxx; SELECT COUNT(*) INTO count_products FROM products; END $$ DELIMITER ; #3. 根据countryName 查到office DELIMITER $$ CREATE PROCEDURE getOfficeByCountry(IN countryName VARCHAR(255)) BEGIN SELECT * FROM offices WHERE country = countryName; END $$ CALL getOfficeByCountry2(‘China‘) #4. 过订单状态返回订单数量 USE yiibaidb; DROP PROCEDURE IF EXISTS CountryOrderByStatus; DELIMITER $$ CREATE PROCEDURE CountryOrderByStatus(IN orderStatus VARCHAR(25), OUT total INT ) BEGIN SELECT COUNT(orderNumber) INTO total FROM orders WHERE STATUS = orderStatus; END$$ DELIMITER ; CALL CountryOrderByStatus(‘Shipped‘, @total); # ‘@‘符号标志的会话变量会等会话结束后才会over, 可以想成一个connection结束。 其他时候可以直接select @变量获得 SELECT @total; #5. a = a + b #use yiibaidb; DROP PROCEDURE IF EXISTS addTwoNum ; DELIMITER $$ CREATE PROCEDURE addTwoNum(INOUT a INT, IN b INT) BEGIN SET a = a + b; END $$ DELIMITER ; #delimiter 这里必须得空格不然会报错 SET @a = 1; CALL addTwoNum(@a , 4); SELECT @a; #6. 根据orderNumber, 返回status4种类型的数量 DROP PROCEDURE IF EXISTS get_order_by_cust; DELIMITER $$ CREATE PROCEDURE get_order_by_cust( IN cust_no INT, OUT shipped INT, OUT canceled INT, OUT resolved INT, OUT disputed INT) BEGIN -- shipped SELECT COUNT(*) INTO shipped FROM orders WHERE customerNumber = cust_no AND STATUS = ‘Shipped‘; -- canceled SELECT COUNT(*) INTO canceled FROM orders WHERE customerNumber = cust_no AND STATUS = ‘Cancelled‘; -- resolved SELECT COUNT(*) INTO resolved FROM orders WHERE customerNumber = cust_no AND STATUS = ‘Resolved‘; -- disputed SELECT COUNT(*) INTO disputed FROM orders WHERE customerNumber = cust_no AND STATUS = ‘Disputed‘; END $$ DELIMITER ; CALL get_order_by_cust(496, @shipped , @canceled , @resolved , @disputed); SELECT @shipped , @canceled , @resolved , @disputed; #7. 根据customerNumber获取creditlimit,然后据此进行判断是在哪个区间 10000 50000 DELIMITER $$ CREATE PROCEDURE GetCustomerLevel(IN p_customerNumber INT(11), OUT p_customerLevel VARCHAR(10) ) BEGIN DECLARE creditlim DOUBLE; SELECT creditLimit INTO creditlim FROM customers WHERE customerNumber = p_customerNumber; IF creditlim>50000 THEN SET p_customerLevel = ‘PLATINUM‘; ELSEIF (creditlim>10000 AND creditlim<=50000) THEN SET p_customerLevel = ‘GOLD‘; ELSEIF creditlim<=10000 THEN SET p_customerLevel = ‘SILVER‘; END IF; END $$ DELIMITER ; CALL GetCustomerLevel(103, @customerLevel); SELECT @customerLevel; DELIMITER $$ CREATE PROCEDURE GetCustomerShipping(IN p_customerNumber INT(4), OUT p_shiping VARCHAR(50)) BEGIN DECLARE customerCountry VARCHAR(50); SELECT country INTO customerCountry FROM customers WHERE customerNumber = p_customerNumber; CASE customerCountry WHEN ‘USA‘ THEN SET p_shiping = ‘2-day Shipping‘; WHEN ‘Canada‘ THEN SET p_shiping = ‘3-day Shipping‘; ELSE SET p_shiping = ‘4-day Shipping‘; END CASE; END $$ DELIMITER ; #调用加别名,自己组成表格形式更加好看见 CALL GetCustomerShipping(112,@shipping); SELECT @shipping AS Shipping SET @customerNo = 112; SELECT country INTO @country FROM customers WHERE customernumber = @customerNo; CALL GetCustomerShipping(@customerNo,@shipping); SELECT @customerNo AS Customer, @country AS Country, @shipping AS Shipping; #上一题区间题目用case进行实现 DELIMITER $$ CREATE PROCEDURE GetCustomerLevel( in p_customerNumber int(11), out p_customerLevel varchar(10))BEGIN DECLARE creditlim double; SELECT creditlimit INTO creditlim FROM customers WHERE customerNumber = p_customerNumber; CASE WHEN creditlim > 50000 THEN SET p_customerLevel = ‘PLATINUM‘; WHEN (creditlim <= 50000 AND creditlim >= 10000) THEN SET p_customerLevel = ‘GOLD‘; WHEN creditlim < 10000 THEN SET p_customerLevel = ‘SILVER‘; END CASE; END$$ #9.将1到5 拼成字符串 #循环遍历while ... do 形式 DELIMITER $$ DROP PROCEDURE IF EXISTS test_mysql_while_loop1$$ CREATE PROCEDURE test_mysql_while_loop1() BEGIN DECLARE X INT(4); DECLARE str VARCHAR(50); SET X = 1; SET str = ‘‘; WHILE X <= 5 DO SET str = CONCAT(str, X, ‘,‘); SET X = X +1; END WHILE ; SELECT str AS num, X AS number; END$$ DELIMITER ; CALL test_mysql_while_loop1; #循环遍历repeat ... until ... end repeat 形式 DELIMITER $$ DROP PROCEDURE IF EXISTS test_mysql_while_loop2$$ CREATE PROCEDURE test_mysql_while_loop2() BEGIN DECLARE X INT(4); DECLARE str VARCHAR(50); SET X = 1; SET str = ‘‘; REPEAT SET str = CONCAT(str, X, ‘,‘); SET X = X +1 ; UNTIL X >5 END REPEAT; SELECT str AS num, X AS number; END$$ DELIMITER ; CALL test_mysql_while_loop2; #循环遍历loop_label .... end loop, 中间会有leave loop_label进行退出, Iterate进行迭代 DELIMITER $$ DROP PROCEDURE IF EXISTS test_mysql_while_loop2$$ CREATE PROCEDURE test_mysql_while_loop2() BEGIN DECLARE X INT(4); DECLARE str VARCHAR(50); SET X = 1; SET str = ‘‘; loop_label: LOOP IF X > 10 THEN LEAVE loop_label; END IF; SET X = X + 1; IF (X MOD 3) THEN ITERATE loop_label; ELSE SET str = CONCAT(str,X,‘,‘); END IF; END LOOP; SELECT str AS num, X AS number; END$$ DELIMITER ; CALL test_mysql_while_loop2; #游标的用法,email_list,字符串放进去,利用游标和concat进行拼接得到varcahr类型 DELIMITER $$ DROP PROCEDURE IF EXISTS build_email_list $$ CREATE PROCEDURE build_email_list(INOUT p_email VARCHAR(500)) BEGIN DECLARE v_finished INTEGER DEFAULT 0; DECLARE v_email VARCHAR(100) DEFAULT ‘‘; -- declare cusor for the empolyee email DECLARE email_cusor CURSOR FOR SELECT email FROM employees; -- decalre NOT FOUND hander DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1; OPEN email_cusor; get_email:LOOP FETCH email_cusor INTO v_email; -- 进行跳出判断 IF v_finished = 1 THEN LEAVE get_email; END IF; SET p_email = CONCAT(v_email, ‘;‘, p_email); END LOOP get_email; CLOSE email_cusor; END $$ DELIMITER ; SET @email_list = ""; CALL build_email_list(@email_list); SELECT @email_list; #11. 创建一张表, 然后自己做实验, 如果出现重复出现的结果的时候可以报你插入的地方重复插入, EXIT, continue DELIMITER $$ DROP PROCEDURE IF EXISTS insertException $$ CREATE PROCEDURE insertException(IN article_id INT, IN tag_id INT ) BEGIN -- 进行声明出现重复代码1062的时候输出 DECLARE CONTINUE HANDLER FOR 1062 SELECT CONCAT(‘duplicate found the (‘,article_id,‘,‘,tag_id,‘)‘) AS msg; INSERT INTO article_tags(article_id,tag_id) VALUES(article_id,tag_id); -- return tag count for the article SELECT COUNT(*) FROM article_tags AS a WHERE a.article_id =article_id AND a.tag_id =tag_id; END $$ DELIMITER ; CALL insertException(1,1); CALL insertException(1,2); CALL insertException(1,3); #利用函数进行判断: create function xxx(param )returns type() #Deterministic ... return (variable) - - DELIMITER $$ DROP FUNCTION IF EXISTS CustomerLevel6 $$ CREATE FUNCTION CustomerLevel6(p_creditLimit DOUBLE )RETURNS VARCHAR(10) DETERMINISTIC BEGIN DECLARE 1v1 VARCHAR(10); IF p_creditLimit > 50000 THEN SET 1v1 = ‘jinzi‘; ELSEIF (p_creditLimit > 10000 AND p_creditLimit <= 50000 ) THEN SET 1v1 = ‘yinzi‘; ELSEIF p_creditLimit <= 10000 THEN SET 1v1 = ‘baijin‘; END IF ; RETURN (1v1); END $$ DELIMITER ; SELECT customerName, CustomerLevel6(creditLimit) FROM customers ORDER BY customerName;
------------关于实例的sql数据库文档 -- 留言发邮箱