`
xia5203166
  • 浏览: 2755 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

mysql存储过程变量使用-bug记录

阅读更多
有一张用户表,字段如下,
CREATE TABLE `tb_account` (
  `a_uid` bigint(20) NOT NULL,
  `a_account` varchar(50) NOT NULL,
  `a_pwd` varchar(50) NOT NULL,
  PRIMARY KEY (`a_uid`),
  KEY `index_1` (`a_account`,`a_pwd`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

然后写了一个登陆的存储过程:
CREATE PROCEDURE `sp_account_login`(in p_account varchar(50),in p_pwd varchar(100))
begin
declare p_uid bigint(20) default 0;
set @now:=unix_timestamp(now());

rett:loop
if p_account is null or p_account='' then
set p_uid:=-2;
leave rett;
end if;

if p_pwd is null or p_pwd ='' then
set p_uid:=-3;
leave rett;
end if;

if not exists (select a_uid from tb_account where a_account = p_account) then
set p_uid:=-11;
leave rett;
end if;

select @uid:= a_uid from tb_account where a_account = p_account and a_pwd = p_pwd;
if @uid is null or @uid='' or @uid<=0 then
set p_uid:=-12;
leave rett;
else
set p_uid := @uid;
leave rett;
end if;
end loop rett;

select p_uid,p_account,@now;
end

这个存储过程在语法上是没有问题的,但是会忽略一个问题:
问题1:因为p_account参数是字符串,在select a_uid from tb_account where a_account=p_account的时候,有时候会出现无法精确匹配的情况,可能是因为mysql执行存储过程的时候,因为没有把p_account参数作为一个字符串去处理,所以会出现串号。

然后修改存储过程为如下
CREATE PROCEDURE `sp_account_login`(in p_account varchar(50),in p_pwd varchar(100))
begin
declare p_uid bigint(20) default 0;
set @now:=unix_timestamp(now());

rett:loop
if p_account is null or p_account='' then
set p_uid:=-2;
leave rett;
end if;

if p_pwd is null or p_pwd ='' then
set p_uid:=-3;
leave rett;
end if;

if not exists (select a_uid from tb_account where a_account = p_account) then
set p_uid:=-11;
leave rett;
end if;

set @sql1=CONCAT('select @uid:=a_uid from tb_account where a_account="',p_account,'" and a_pwd="',p_pwd,'";');

prepare s1 from @sql1;
execute s1;
deallocate prepare s1;

if @uid is null or @uid='NULL' or @uid='' or @uid<=0 then
set p_uid:=-12;
leave rett;
else
set p_uid := @uid;
leave rett;
end if;
end loop rett;

select p_uid,p_account,@now;
end$$


这个时候,组装了一条sql语句,但是发现还是串号。继续排查问题。
发现出现串号的时候,是把上一次的账号登陆的p_uid返回了,所以断定肯定是缓存。

在该存储过程里,申明了一个局部变量p_uid,一个用户变量@uid,首先查询a_uid字段值给用户变量@uid,然后把用户变量赋值给局部变量。

局部变量每次执行存储过程的时候,mysql会生成一个新的局部变量,所以不会出现问题,
那问题肯定出现在用户变量上,用户变量对client全局有效,然后尝试修改如下:

CREATE PROCEDURE `sp_account_login`(in p_account varchar(50),in p_pwd varchar(100))
begin
declare p_uid bigint(20) default 0;
set @now:=unix_timestamp(now());

rett:loop
if p_account is null or p_account='' then
set p_uid:=-2;
leave rett;
end if;

if p_pwd is null or p_pwd ='' then
set p_uid:=-3;
leave rett;
end if;

if not exists (select a_uid from tb_account where a_account = p_account) then
set p_uid:=-11;
leave rett;
end if;

set @uid:=0;
set @sql1=CONCAT('select @uid:=a_uid from tb_account where a_account="',p_account,'" and a_pwd="',p_pwd,'";');

prepare s1 from @sql1;
execute s1;
deallocate prepare s1;

if @uid is null or @uid='NULL' or @uid='' or @uid<=0 then
set p_uid:=-12;
leave rett;
else
set p_uid := @uid;
leave rett;
end if;
end loop rett;

set @uid:=0;
select p_uid,p_account,@now;
set p_uid:=0;
end if;

在select @uid:=a_uid from tb_account的时候,先set @uid:=0;把上一次执行的变量先赋值为0,然后执行结束后,再赋值为0一遍,这里有点重复作用了,但是在没信心的情况下,先这么试着。

OK,改完后,再写了段代码测了一遍,没问题了
让测试测了几遍,也没问题了,好了,基本确定问题在哪里了,下面就知道问题出在哪里了,继续优化。。。
分享到:
评论

相关推荐

    Mysql数据库驱动mysql-connector-java-5.1.41-bin.jar

    - 其他特性:包括预编译的SQL语句(PreparedStatement)、批处理、存储过程调用等。 6. **安全性与优化**: - 使用最新的驱动版本可以提高性能并获得新的安全补丁。 - 应该避免在代码中硬编码数据库凭证,而是...

    mysql-connector-java-8.0.21.rar 数据库连接依赖最新版

    考虑使用环境变量或配置文件,并确保它们的安全存储。 6. **连接池的使用**: 对于高并发的应用,使用连接池如HikariCP、C3P0或Apache DBCP可以更高效地管理数据库连接,提高性能并减少资源消耗。 7. **事务管理*...

    linux 64位 mysql-5.6.39-linux-glibc2.12-x86_64.tar.gz

    这个版本引入了许多新特性、改进和bug修复,进一步提高了MySQL数据库系统的性能、可靠性和安全性。对于那些希望在Linux 64位环境下运行MySQL服务的应用程序来说,这是一个非常合适的版本。 #### 主要特性 - **...

    mysql-5.7.36-linux-glibc2.12-x86_64

    MySQL是世界上最受欢迎的关系型数据库管理系统(RDBMS)之一,尤其在Web应用程序中广泛使用。这个压缩包"mysql-5.7.36-linux-glibc2.12-x86_64"包含了针对Linux操作系统的MySQL服务器版本5.7.36,该版本专为glibc...

    mysql-connector-java-5.1.40-bin.rar

    安装和使用"mysql-connector-java-5.1.40-bin.jar"的过程通常包括以下几个步骤: 1. 下载:你需要从MySQL官方网站或者其他可信来源下载这个JAR文件。 2. 配置Classpath:将这个JAR文件添加到Java项目的类路径...

    mysql-for-visualstudio-1.2.6.msi 官方下载原版

    5. **调试支持**:对于存储过程和函数,插件提供了调试功能,可以在Visual Studio中设置断点,检查变量值,进行单步调试。 6. **项目集成**:在Visual Studio的解决方案资源管理器中,可以直接添加和管理MySQL...

    mysql-5.5.57-linux-glibc2.12-x86_64.tar.gz

    MySQL 5.5.57还支持各种高级特性,如ACID事务、存储过程、触发器、视图、索引、外键约束等,为企业级应用提供了可靠的数据存储和管理能力。在使用过程中,应关注性能优化、复制、备份恢复策略以及定期的安全评估和...

    mysql-connector-java-5.1.35 MySQL的jdbc驱动jar

    同时,避免在代码中硬编码数据库凭证,考虑使用环境变量或配置文件存储敏感信息。 10. **JDBC驱动的替代方案** 虽然MySQL JDBC驱动是最常用的,但还有其他选择,如MariaDB Connector/J或Apache Calcite的Avatica。...

    mysql驱动包jdbc(mysql-connector-java-3.1.14)

    10. **安全性**:使用JDBC驱动时,要注意数据安全,避免在代码中硬编码数据库凭证,可以使用环境变量、配置文件或加密手段存储敏感信息。此外,定期更新驱动至最新版本,以修复可能的安全漏洞。 了解这些知识点,将...

    MYSQL官方文档(全英文)

    - MySQL添加了一些非标准的SQL语法特性,如自定义函数和存储过程。 - **1.8.2 MySQL与标准SQL的区别** - 由于MySQL自身的特性和历史原因,存在与标准SQL不一致的地方。 - **1.8.3 MySQL如何处理约束** - MySQL...

    MySql参考文档

    - 描述了在 MySQL 开发过程中使用的工具和技术。 - **1.9.5 MySQL 的支持者** - 致谢那些对 MySQL 项目给予支持的企业和个人。 #### 二、安装与升级指南 **2.1 通用安装指南** - **2.1.1 选择 MySQL 版本和发行...

    mysql-8.0-en-20210403.pdf

    公用表表达式(CTE)是一种临时结果集,它可以在SQL查询中定义并可重复使用,类似于存储过程中的局部变量。 除了新特性,MySQL 8.0的文档也列出了与之前版本相比新增、弃用或移除的服务器和状态变量以及选项。这些...

    MySQL 8.0 Reference Manual - Including MySQL NDB Cluster 8.0

    - **废弃变量**:列出了在 MySQL 8.0 中被废弃或移除的变量和选项,帮助用户了解哪些设置不再推荐使用。 - **变动说明**:详细说明了这些变动的原因及其对现有应用程序的影响。 #### 三、MySQL 标准兼容性 ##### ...

    mysql-installer-5.7.28.0.zip

    10. **存储过程和函数的改进**:包括支持窗口函数和改进的变量处理,使存储过程和函数编写更加灵活。 通过运行"mysql-installer-community-5.7.28.0.msi"文件,用户可以一站式安装MySQL Server、Workbench、...

    mysql-connector-java.zip

    - 避免硬编码数据库凭证,使用环境变量或配置文件来存储敏感信息。 - 定期更新驱动以获取最新的安全补丁和性能改进。 总结来说,MySQL Connector/J是Java开发者与MySQL数据库交互的关键组件,这两个版本的JDBC...

    MySQL 8.1 Reference Manual - Including MySQL NDB Cluster 8.1

    如果在使用过程中遇到任何问题或发现Bug,可以通过以下途径进行反馈: - 访问官方论坛寻求帮助。 - 联系Oracle的技术支持团队。 - 提交错误报告至MySQL的Bug追踪系统。 #### 6. MySQL与SQL标准的兼容性 MySQL在...

    MySQL中服务器状态变量全解.pdf

    MySQL作为一款广泛使用的开源关系型数据库管理系统,在实际运维过程中,服务器状态变量的监测与分析至关重要。通过这些状态变量,DBA(数据库管理员)不仅能够实时掌握数据库的运行状况,还能借此对性能问题进行定位...

    MySQL 5.7参考手册

    - **废弃的系统变量**:标识了MySQL 5.7中不再推荐使用的系统变量。 - **移除的系统变量**:明确MySQL 5.7中完全移除的系统变量。 ### MySQL 5.7的信息来源 #### 1.6 MySQL Information Sources - **网站资源**:...

    MySQL-5.7.pdf

    MySQL支持一系列重要功能,包括存储过程、触发器、视图、信息模式、分布式(XA)事务和更多。 关于MySQL 5.7的新特性,文档中提到了许多改进,例如优化器的改进、性能提升、安全性和可用性的增强等。例如,MySQL ...

    mysql5.7.4下载地址

    为了能够在命令行中直接使用 MySQL 命令,需要将 MySQL 的 bin 目录添加到系统的环境变量中。具体操作步骤如下: 1. 打开控制面板 -&gt; 系统和安全 -&gt; 系统 -&gt; 高级系统设置 -&gt; 环境变量。 2. 在“系统变量”区域找到...

Global site tag (gtag.js) - Google Analytics