mysql 存储过程中的 prepare语句(存储过程中动态增减表字段)

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lqx_sunhan/article/details/79852063

1.问题的由来

前几天写项目的时候,有用到存储过程,需要在存储过程中创建一张临时表,然和在动态增减临时表的字段,所以就用到了mysql的prepare预编译语句。

2.这个语法是干嘛的

基本语法:

PREPARE stmt from '你的sql语句';
EXECUTE stmt (如果sql有参数的话, USING xxx,xxx); // 这里USING的只能是会话变量
DEALLOCATE PREPARE stmt; 

这三句话分别就是预定义好sql.
执行预定义的sql
释放掉数据库连接
使用这个语法便可以在存储过程中写一些ddl语句,但是在网上看到的是在存储过程中最好是不要写ddl,因为ddl操作会锁表,总之就是不建议在存储过程中去更改表结构。不过我们这里是对临时表的改变,是不影响的啦。

3.还有什么用

扩展一下这个语法还有什么作用呢?

  • 他还可以在存储过程中动态的拼接表名,字段名,来达到动态查询的效果
  • sql语句中还可以用?来代表参数,这样可以有效的防止sql注入

4.实例用法

1.

delimiter //
create procedure myTest()
begin
set @_sql = 'select ? + ?';
set @a = 5;
set @b = 6;
PREPARE stmt from @_sql; // 预定义sql
EXECUTE stmt USING @a,@b;// 传入两个会话变量来填充sql中的 ?
DEALLOCATE PREPARE stmt; // 释放连接
end //

调用上面的存储过程,会得到11的结果,就是这么简单,关于存储过程我的其他博客里面有,可以去看,值得一提的是,如果是要动态的选择表名,表名并不能用 ? 来当占位符。我们只能采用字符串拼接的方法。

2.

delimiter //
create procedure myTest(in columnName varchar(32)) // 传入一个字符串
BEGIN
drop table if exists tmpTable; // 如果临时表存在先删除掉
set @_sql = concat('create temporary table if not exists tmpTable( ', columnName, ' varchar(32), id int(11), _name varchar(32));'); // 创建临时表的语法,我们把传入的参数拼接进来
PREPARE stmt from @_sql;    
EXECUTE stmt;
DEALLOCATE PREPARE stmt;  // 执行
desc tmpTable;
end //

以上存储过程我们可以看到我们传入的字符串可以动态的添加到临时表里面去。
创建临时表时还可以直接从结果集创建。 create temporary table tmpTable select * from tableName;

展开阅读全文

mysql存储过程中PREPARE语句的问题

04-11

我在存储过程中利用了PREPARE语句,但是在CALL这个时候报错,请高手们看看是那个地方有问题,创建过程的时候没报错。rn具体代码:rn[code=sql]rn-- 原本是这样的查询语句rnSELECT t1.bankprovincecode,t1.bankprovincename,'2' AS area_level,COUNT(t3.corpid)AS c_corpid rnFROM bankbranchparams AS t1 rnINNER JOIN corpinfo AS t3 ON t1.bankbranchleadercode=t3.bankbranchleadercode rnWHERE t3.applydate <= '20160325' AND t3.version<>'entjxcstd'rnGROUP BY t1.bankprovincecode,t1.bankprovincename;rn-- 创建过程rnDROP PROCEDURE IF EXISTS proc_test;rnCREATE PROCEDURE proc_testrn(v_cname VARCHAR(20),rn v_cname2 VARCHAR(20),rn v_nextlevel VARCHAR(10),rn i_date VARCHAR(20))rnBEGINrnSET @sqlstr1=CONCAT('SELECT t1.',v_cname,'t1.',v_cname2,v_nextlevel,rn'AS area_level,COUNT(t3.corpid)AS c_corpid FROM bankbranchparams AS t1 rnINNER JOIN corpinfo AS t3 ON t1.bankbranchleadercode=t3.bankbranchleadercode rnWHERE t3.applydate <=',i_date, 'AND t3.version<>','entjxcstd',rn'GROUP BY t1.',v_cname,'t1.',v_cname2);rnrnPREPARE stmt1 FROM @sqlstr1;rnEXECUTE stmt1;rnrnEND;rnCALL proc_test('bankprovincecode','bankprovincecodename','2','20160325');rnrn[/code]rn报错:rn[SQL]CALL proc_test('bankprovincecode','bankprovincecodename','2','20160325');rn[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't3.version<>entjxcstdGROUP BY t1.bankprovincecodet1.bankprovincecodename' at line 3 论坛

存储过程中的SQL语句

07-19

[code=SQL]rnUSE [Warehouse]rnGOrn/****** Object: StoredProcedure [dbo].[SP_T_Operation_SelectAll] Script Date: 07/19/2012 14:21:07 ******/rnSET ANSI_NULLS ONrnGOrnSET QUOTED_IDENTIFIER ONrnGOrn------------------------------------rn--用途:模糊查询 rn--项目名称:rn--说明:rn--时间:2012-7-17 15:00:36rn------------------------------------rnALTER PROCEDURE [dbo].[SP_T_Operation_SelectAll_InOut]rn(rn @SheetID varchar(20),rn @date1 varchar(25),rn @date2 varchar(25),rn @SheetOwner varchar(10),rn @CostCenterCode varchar(10),rn @ProductName nvarchar(100)rn)rnASrnBEGINrn DECLARE @sql nvarchar(MAX)rn SET @sql ='rn select rn a.SheetID,a.OperationDate,a.OriginalSheetID, rn c.ProductName,a.ReturnReason,rn casern when a.OriginalSheetID="" or a.OriginalSheetID is NULL then b.Quantityrn end as outs,rn casern when a.OriginalSheetID<>"" or a.OriginalSheetID is not NULL then b.Quantityrn end as ins,rn b.UnitPrice,rn d.UserName,b.CostCenterCodern from T_Operation a left join rn T_OperationDetail b on a.SheetID=b.SheetID rn left join T_Product c on b.ProductID=c.ProductIDrn left join T_User d on a. SheetOwner=d.UserIDrn where 1=1rn ' rn IF @SheetType IS NOT NULL AND @SheetType <>''rn SET @sql=@sql+' and A.SheetType ='+@SheetType;rn rn IF @date1 IS NOT NULL AND @date1<>'' and @date2 IS NOT NULL AND @date2<>''rn SET @sql=@sql+' and A.OperationDate >='''+ CONVERT(varchar(100), @date1, 120)+''' and A.OperationDate <='''+CONVERT(varchar(100), @date2, 120)+'''';rn rn IF @SheetOwner IS NOT NULL AND @SheetOwner<>''rn SET @sql=@sql+' and d.UserName LIKE(''%'+@SheetOwner+'%'')';rn rn IF @CostCenterCode IS NOT NULL AND @CostCenterCode<>''rn SET @sql=@sql+' and B.CostCenterCode LIKE(''%'+@CostCenterCode+'%'')';rn rn IF @ProductName IS NOT NULL AND @ProductName<>''rn SET @sql=@sql+' and C.ProductName LIKE(''%'+@ProductName+'%'')';rn rn PRINT (@sql)rn rn EXEC (@sql)rn rnENDrn[/code]rn主要是这一段rn[code=SQL]rncasernwhen a.OriginalSheetID="" or a.OriginalSheetID is NULL then b.Quantityrnend as outs,rncasernwhen a.OriginalSheetID<>"" or a.OriginalSheetID is not NULL then b.Quantityrnend as ins,rn[/code]rn想实现当OriginalSheetID为空,则将Quantity当做OUTS输出rn当OriginalSheetID不为空,则将Quantity当做ins输出rn应该怎么写呢? 论坛

没有更多推荐了,返回首页