关于存储过程的安全性

最近在做大型聊天室项目,我是负责数据库和软件后台这一块的。为了安全性性考虑,我们开发小组决定将所有SQL语句封装成存储过程,然后只开通一个远程访问sql账户,并且将这些存储过程的执行权限赋予到这个sql账户中去。编写存储过程的时候我们的存储过程名称都取得比较有意义和规律,为了进一步的提高安全,我们小组又把存储过程的名称再进行了一次加密。

关于存储过程的性能

大型聊天室程序读取数据库是非常平凡的,比如每一个用户进入一个聊天室,他首先要从数据库中读取在这个聊天室中的玩家信息,而每一个玩家信息字段差不多有接近100个字段,且分布到各个扩展表中,有些时间某个扩展表的多条数据会和主表中的某一条数据相关联,那么就需要用到分部查询了。这样的查询在程序中还是比较好实现的,但是也有他的弊端,比如房间中了1万个用户,那么我们要读取到一万的用户的基本信息,就需要查询1万次数据库。如果我们还需要显示这一万个用户的详细信息,那么就需要查询几万次数据库了,这样做显然不行。

一次性读取10000条数据,远远比一次读取10条数据,连续读1000次的效率快。

我们自己的办法就是将逻辑处理写入到存储过程当中去,服务端只需要调用一个这样的存储过程就能达到目的:

create proc proc_name

(

@userIds varchar(max)  --这个房间的所有用户Id,以逗号分隔

)

as

begin

//逻辑处理,各种循环 判断 游标

select * from #tableName

end

EXEC proc_name '1,2,3,4,5,6,7'

这样就只需要访问一次数据库就能得到所有数据。

下面分享一下这样的代码

 create proc [dbo].[Proc_#CombinationService]  (  @SplitString nvarchar(100),  @FieldSeparator nvarchar(10)='|',  @GroupSeparator nvarchar(10)='&',  @ReturnData nvarchar(2000) output  )  AS  BEGIN  DECLARE @CurrentIndex int;  DECLARE @NextIndex int;  DECLARE @ReturnText nvarchar(100);  DECLARE @Return nvarchar(1000)=''  DECLARE @ServiceNumber varchar(100);  DECLARE @ServiceName varchar(100);  DECLARE @ServiceLevel varchar(100);  DECLARE @IconNumber varchar(100);  DECLARE @Explain varchar(150);  SELECT @CurrentIndex=1;  WHILE(@CurrentIndex<=len(@SplitString))  BEGIN  SELECT
@NextIndex=charindex(@FieldSeparator,@SplitString,@CurrentIndex);IF(@NextIndex=0 OR @NextIndex IS NULL)  SELECT @NextIndex=len(@SplitString)+1;  SELECT @ReturnText=substring(@SplitString,@CurrentIndex,@NextIndex-@CurrentIndex);select @ServiceNumber=ServiceNumber,@ServiceName=ServiceName,@ServiceLevel=ServiceLevel,  @IconNumber=IconNumber,@Explain=Explain  from UserServiceInfo where ServiceNumber=@ReturnText  set @Return=@ServiceNumber+@FieldSeparator+@ServiceName+@FieldSeparator+@ServiceLevel+@FieldSeparator+@IconNumber+@FieldSeparator+@Explain+@GroupSeparator+@Return  SELECT @CurrentIndex=@NextIndex+1;  END  set @ReturnData=@Return  RETURN;  END  
create PROCEDURE [dbo].[Proc_#UsersInfo_GetDataInfo]  (  @SplitString nvarchar(100),  @FieldSeparator nvarchar(10)='|'  )  AS  begin  CREATE TABLE #t(UserNumber INT PRIMARY KEY,NickName varchar(20),LiangNumber varchar(20),GroupNumber int,Avatar varchar(100),ServicesNumber varchar(100),ReturnData nvarchar(2000))  DECLARE @CurrentIndex int;  DECLARE @NextIndex int;  DECLARE @ReturnText nvarchar(100);  DECLARE @ReturnData nvarchar(2000);  DECLARE @UserNumber INT;  DECLARE @NickName varchar(20);  DECLARE @LiangNumber varchar(20);  DECLARE @GroupNumber int;  DECLARE @Avatar varchar(100);  DECLARE @ServicesNumber nvarchar(100);  SELECT @CurrentIndex=1  WHILE(@CurrentIndex<=len(@SplitString))  BEGIN  SELECT @NextIndex=charindex(@FieldSeparator,@SplitString,@CurrentIndex);  IF(@NextIndex=0 OR @NextIndex IS NULL)  SELECT @NextIndex=len(@SplitString)+1;  SELECT @ReturnText=substring(@SplitString,@CurrentIndex,@NextIndex-@CurrentIndex);  select  @UserNumber=UserNumber,@NickName=NickName,@LiangNumber=LiangNumber,@GroupNumber=GroupNumber,@Avatar=Avatar,@ServicesNumber=ServicesNumber from View_ClientUserList  where UserNumber=@ReturnText  exec [Proc_#CombinationService] @ServicesNumber,'|','#',@ReturnData output  insert into #t(UserNumber,NickName,LiangNumber,GroupNumber,Avatar,ServicesNumber,ReturnData)   values(@UserNumber,@NickName,@LiangNumber,@GroupNumber,@Avatar,@ServicesNumber,@ReturnData)  SELECT @CurrentIndex=@NextIndex+1;  END  select * from #t  drop table #t  end  

[Proc_#UsersInfo_GetDataInfo] '1036|1039|1035|','|'

结果

1035 NULL 65484 3 NULL 2 2|土财主|1|[tcz]|一次性充值5万#
1036 test1 10361036 NULL NULL 1|2|3 3|大款|1|[dk]|使用100万虚拟币#2|土财主|1|[tcz]|一次性充值5万#1|贵族|1|[gz]|消费超过1万#
1039 test 1037 1 NULL 2|3 3|大款|1|[dk]|使用100万虚拟币#2|土财主|1|[tcz]|一次性充值5万#

以上操作虽然降低了程序与数据库之间的链接频率,但是却加大了数据库的运算量和数据的传输量。

最后我们小组放弃了让存储过程从数据库读取最后一列的数据(@ReturnData),而是将这个数据表里面的数据一次性读到程序内存当中去,然后在程序里面根据它的编号集(倒数第二列)来进行解析。

MSSql存储过程高效应用相关推荐

  1. mysql中leave和_MySQL数据库之Mysql存储过程使用LEAVE实现MSSQL存储过程中return语法

    本文主要向大家介绍了MySQL数据库之Mysql存储过程使用LEAVE实现MSSQL存储过程中return语法 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. DELIMITER ...

  2. Golang调用mssql存储过程

    由于项目需要使用GO来调用mssql存储过程,所以不得已研究一下,整个过程是比较费劲的,因为本人还处于GO小白状态,公司项目是基于网狐的棋牌平台,网狐项目不得不说还是比较整洁清晰的,但是由于出道以来一 ...

  3. python执行sqlserver存储过程_python – 从SqlAlchemy调用MSSQL存储过程

    看起来SqlAlchemy似乎不支持调用存储过程.有没有人找到适用于SQL Server的解决方法? 样品程序: CREATE PROCEDURE list_lock_set @name varcha ...

  4. php mssql 存储过程 输入参数,MSSQL_SQL Server存储过程中使用表值作为输入参数示例,在2008之前如果我们想要将表作 - phpStudy...

    SQL Server存储过程中使用表值作为输入参数示例 在2008之前如果我们想要将表作为输入参数传递给SQL Server存储过程使比较困难的,可能需要很多的逻辑处理将这些表数据作为字符串或者XML ...

  5. 关于MSSQL存储过程中使用游标的一个小例子(学习)

    声明:本例转自http://hi.chinaunix.net/?214950/viewspace-1713,主要是为了学习之用 比如有个表,内容如下 id,text 1,春花秋月何时了 2,往事知多少 ...

  6. mssql 存储过程 group by 集合并逗号要开某字段

    代码 Alter PROCEDURE groupby_table_splitFieldname     @groupby varchar(50),@tablename varchar(50),@fie ...

  7. mysql存储过参数拼接_mysql 存储过程动态拼接sql并执行赋值

    CREATE DEFINER = CURRENT_USER PROCEDURE `NewProc`(in _xnb varchar(50)) BEGIN ## 定义变量 DECLARE _num FL ...

  8. cms概述 。比较shopex和ecshop区别 。smarty模板引擎的入门

    cms概述 为了找到一个合适的cms网站系统,我花了一番功夫搜索了多种cms,包括我用过的和没用过的,知道的和不知道的,当然,必须是开源的.免费的.生成静态页面的.到各自的官方网站,查看了有关资料,下 ...

  9. 国内免费(开源)CMS系统【大全】

    天猫内部优惠券 在网上搜集了一下国内的CMS程序,包括了类型,脚本,及其特点和评价,希望能对大家有所帮助, 首先还是介绍一下什么是CMS:CMS 网站内容管理系统, 即 Content Managem ...

最新文章

  1. 网站外链如何发布才能更快的得到高排名呢?
  2. 收藏:软件开发、软件收藏
  3. 单点登录(SSO)—简介 1
  4. oracle list 分区详解,oracle的List分区及分区索引
  5. A3D8的水–WaterMaterial for Alternativa3D 8
  6. 【华为云技术分享】《跟唐老师学习云网络》 - Tcpdump大杀器抓包
  7. textarea的maxlength属性兼容解决方案
  8. Ponemon Institute告诉你,大数据正在勾搭网络安全
  9. AR:Unity与iOS交互(入门篇)
  10. 安装Ubuntu18
  11. VBS教程---第一篇
  12. 三级模式两级映像/数据库系统结构
  13. word文档 目录 导航窗格 整理
  14. 《企业管理学》—战略管理与目标管理知识点总结
  15. session 、cookie、token的区别及联系
  16. 青龙羊毛——猫咪放羊(搬运)
  17. 你也能成为 “最强大脑”
  18. Android 11.0 PackageManagerService(一)工作原理和启动流程
  19. Python当中reverse()函数
  20. Java1.7版本解码base64_JDK Base64 编解码 1.7 和 1.8 的坑

热门文章

  1. Mac上webstorm与git仓库建立连接
  2. 矩阵LU分解分块算法实现
  3. 苹果系统下如何粘贴复制?
  4. .NET新手系列(六)
  5. 浅析微信支付:统一下单接口
  6. Centos7下的Ambari安装
  7. 使用Innobackupex快速搭建(修复)MySQL主从架构
  8. 动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
  9. day1 作业编写登录窗口
  10. 小朋友的视频直播之 nginx-rtmp