题外话,为什么不用mysql数据库存储过程的存储过程

一、存储过程与函数的区别:
  1.一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。
  2.对于存储过程来说可以返回参数(output),而函数只能返回值或者表对象。
  3.存储过程一般是作为一个独立的部分来执行,而函数可以作为查询语句的一个部分来调用,由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。
二、存储过程的优点:
  1.执行速度更快 & 在数据库中保存的存储过程语句都是编译过的
  2.允许模块化程序设计 & 类似方法的复用
  3.提高系统安全性 & 防止SQL注入
  4.减少网络流通量 & 只要传输存储过程的名称
系统存储过程一般以sp开头,用户自定义的存储过程一般以usp开头
三、定义存储过程语法,"[" & 里面的内容表示可选项
  create proc 存储过程名
  @参数1&&&&&&&&数据类型 [=默认值] [output],
  @参数2&&&&&&&&数据类型 [=默认值] [output],
  SQL语句
四、简单的一个例子
  定义存储过程:
  create proc usp_StudentByGenderAge
  @gender nvarchar(10) [='男'],
  @age int [=30]
  select * from MyStudent where FGender=@gender and FAge=@age
  执行存储过程:
  Situation One(调用默认的参数):
  exec usp_StudentByGenderAge
  Situation Two(调用自己指定的参数):
  exec usp_StudentByGenderAge '女',50
  或者指定变量名&&&&&&&&exec usp_StudentByGenderAge @age=50,@gender='女'
  对存储过程进行修改
  alter proc usp_StudentByGenderAge
  @gender nvarchar(10) [='男'],
  @age int [=30],
  --加output表示该参数是需要在存储过程中赋值并返回的
  @recorderCount int output&
  select * from MyStudent where FGender=@gender and FAge=@age
  set @recorderCount=(select count(*) from MyStudent where FGender=@gender and FAge=@age)
--output参数的目的,就是调用者需要传递一个变量进来,然后在存储过程中为该变量完成赋值工作,存储过程执行完成以后,将执行的对应结果返回给传递进来的变量。(与C#中的out原理一模一样)
调用(记住这里的语法!)因为该存储过程前面还有其他参数,所以要把 @recorderCount写上,该存储过程执行后,相当与完成了以上的查询工作,同时将查询结果得到的条数赋值给了@count变量。(@count是当做参数传给usp_StudentByGenderAge,当存储过程执行完毕以后,将得到的条数返回给@count)
  declare @count int
  exec usp_StudentByGenderAge @recorderCount=@count output
  print @count
五、使用存储过程完成分页
1、存储过程代码
&  &create proc usp_page
  @page int,&&&&&&&&& ---一页显示多少条记录
&  &@number int,&& ---用户选择了第几页数据
&  begin
&  select * from
&  --小括号里面内容是专门得到排列好的序号
&    select& ROW_NUMBER() over(order by(Fid))& as number
&    from MyStudent
&  ) as t
&  where t.number&= (@number-1)*@page+1 and t.number&=@number*@page
2、实现分页效果对应的ADO.NET代码:
1 private void button1_Click(object sender, EventArgs e)   { 2   string connStr = @"server=.\database=MyDB;integrated security=true"; 3   using (SqlConnection conn = new SqlConnection(connStr)) 4   { 5     //打开数据库连接 6     conn.Open(); 7     //用存储过程名作为Command处理的对象 8     string usp = "usp_page"; 9     using (SqlCommand cmd = new SqlCommand(usp, conn))10     {11       //执行的是存储过程语句12       mandType = CommandType.StoredP        //textBox1.Text是指显示多少条记录13       cmd.Parameters.AddWithValue("@page", textBox1.Text.Trim());14       //textBox.Text是指用户选择了第几页15       cmd.Parameters.AddWithValue("@number", textBox2.Text.Trim());16       //用list作为数据源来实现17       List&Person& p = new List&Person&();18       using (SqlDataReader reader = cmd.ExecuteReader())19       {20         if (reader.HasRows)21         {22           while (reader.Read())24           {25             Person p1 = new Person();26             p1.FName = reader.GetString(1);27             p1.FAge = reader.GetInt32(2);28             p1.FGender = reader.GetString(3);29             p1.FMath = reader.GetInt32(4);30             p1.FEnglish = reader.GetInt32(5);31             p.Add(p1);32           }33         }34       }35       dataGridView1.DataSource =36     }37   }38 }
下面是自定义的Person类
1 class Person 2 {3 public string FName { get; set; }4 public int FAge { get; set; }5 public string FGender { get; set; }6 public int FMath { get; set; }7 public int FEnglish { get; set; }8 }
阅读(...) 评论()本文是一篇有争议的文章,甚至有可能是一篇争议非常大的文章,可能争来争去依然无法得到一个统一的意见。
个别公司的技术决策者要求团队的开发人员在编写数据访问层的时候,禁止在程序中出现任何的SQL语句,禁止使用Entity Library,禁止使用NBear、NHibernate、IBatis、Entity Framework等ORM框架,只允许使用存储过程。试想一下,您的公司是否是这样子的?您的身边有没有这样的朋友,他们的公司存在这样或类似这样的情况吗?
对于开发人员来说,使用存储过程的话,工作量比以前要大很多,而且涉及到表的字段更改,项目重构也是个非常麻烦的问题,使用ORM很方便就可以实现数据的CRUD功能,多表操作也非常的容易,原来写很少的代码就可以操作数据,现在却要写很多的代码。本来公司给的时间就短,项目紧,现在这么一搞,工作量一下就增加了不少,再者,如果需求一旦发生变化,不可避免的数据库就得增加或修改某些字段,相应的存储过程跟数据访问层的方法都得做调整,开发人员的日子不好过了。
对于公司的决策者来说,性能问题是不可以妥协的,无论付出多大代价,既然做出了决定,那么就没什么好讨论的。
结果可想而知,最终是按照决策者的决定,开发人员加班加点的做开发,既然决策者都已经做了决定,似乎再讨论用不用存储过程就是一个非常敏感的话题,再讨论类似的问题的话,开发人员所面临的处境就可能是尴尬的,在某些公司甚至是危险的。无论怎样,开发人员可能最终都很难改变决策者的决定。
决策者的心声
带着这些疑惑,我跟多位决策者进行沟通,搜集了他们的意见,总结下来的话,大概就是以下几点:
性能问题。经过测试,使用ORM比直接调用存储过程慢10倍。如果是做软件项目或软件产品,使用ORM问题不大,可是如果是以运营为主(访问量较大)的Web网站,性能上就会有问题。并发问题。一旦访问量较大并且达到一定数量级的时候,ORM就可能会出现并发问题。DBA的能力受限。一旦出现性能问题,如果是按照写存储过程的方式来做,公司可以招来技术实力强的DBA直接改存储过程进行优化,而如果是使用ORM的话,那么DBA就很难进行优化,因为DBA很难读懂ORM写的程序,更不知道ORM内部的实现方式,这样一来,DBA的能力就得不到施展。不愿意被微软绑架。以Entity Framework为例,Entity Framework不是开源的,如果出现性能问题,不能够看到源代码,这可能是一个风险。再者,一个强有力的公司强有力的团队,如果没有自己的技术,总是使用微软的不开源的框架,这怎么可以?Entity Framework是微软的产品,微软的产品只适合中小型的公司做开发,大的互联网公司是不敢用的,甚至他们可能采用Java+Oracle来做,一旦达到一定数量级,微软的东西就可能会出现问题。
笔者的心声
在充分理解了决策者的心声以后,我思绪万千,心中久久不能平静。终于,在把很多东西看淡,抛开杂念,在这样一个宁静的夜晚,也坦诚的把我的想法一一阐述,分别针对决策者的心声,谈一谈我的个人看法。
1.到底什么是性能问题?存在不存在性能问题?&&& 来看下测试是如何做的,使用存储过程进行插入或删除操作,分别使用存储过程和Entity Framework,循环10000次或者1000000次操作,然后整体上存储过程要比使用Entity Framework要快10倍。实际场景是怎样的呢? 实际的场景是用户点击页面上的按钮,执行了1次操作,我们假定按照写存储过程的方式来做,用户这1次操作可能需要0.001秒,而使用Entity Framework要慢10倍,用了0.01秒,那么这0.001秒比0.01秒的确是快10倍,但是对用户来说,可能根本就没有明显的差距,因为这么微弱的时间用户是体会不出来的。我们开发的程序,对用户来说,我们的产品会不会因为这0.001秒跟0.01秒的差距而打折扣呢?这微弱的差距是严重性能问题?还是可以忽略不计?
2.到底存在不存在并发问题?
诚然,可能之前有团队使用ORM开发高并发的项目,他们在运营中出现了并发问题,可是DBA又无法查出来到底是什么地方导致了并发问题,最终把一切的一切归咎在ORM上。
亲爱的朋友们,让我们理智的冷静的来分析下两者的技术实现上的不同吧。
直接调用存储过程:打开数据库连接--》执行编译好的数据库语句--》关闭数据库连接
ORM:打开数据库连接--》把对象解释成SQL语句--》执行SQL操作--》关闭数据库连接
通过比对我们可以发现,ORM就可以比作是一个SQL生成器,它把对象解释,拼一个SQL语句出来,然后在执行这个SQL语句,由于还需要解释,就相当于多了一步翻译的工作,因此,就比存储过程慢了一点点,那么慢的这一点点会不会出现并发问题?我的意见是并发问题多半是由于锁的影响,只要不产生锁,就不会有并发问题。正因为如此,高并发的项目开发,多半是忌讳使用事务,有的程序员手写异常后的数据库回滚语句(有些滑稽哈,但事实上就是这样),项目中也不推荐使用游标跟触发器。
3.DBA能力受限。诚然,DBA看不懂ORM写的程序,更加不明白ORM内部的实现原理。但是,DBA是可以跟程序员配合,利用SQLProfile等工具,看到最终SQL语句是如何执行的。也就是说,DBA的能力也是依然可以发挥出来的,只不过是需要跟程序员配合而已,或者DBA需要熟悉如何调试、跟踪。如果说全部写存储过程了,DBA能力是放开了,可是程序员的能力就受限了,譬如说,在进行大批量的数据插入的时候,大家都知道,.ADO.NET2.0的一个新特性SqlBulkCopy是多么的快,估计这是DBA无法优化的。对SqlBulkCopy不熟悉的朋友,请参考《》。
很多时候,一个软件性能的优化,需要从整体去考虑,并不一定是说出现数据库性能问题,就一定是DBA的责任,或者说一定是程序员的责任。在DBA跟程序员之间难道就真的像插销跟插板之间那样,职责分的特别的清楚?很多时候我们得充分利用存储过程的特性,跟.NET平台的一些优良特性,选择适合我们的来进行开发,没有什么是最佳的,但是对我们来说,适合我们就好。
从另外的角度考虑,其实在项目初期,DBA就应该参与进来,进行数据库的设计了,而一旦数据库设计好了,设计得并不规范,存储过程也些了成千上万了,将来一旦出现性能问题,相信也够DBA喝一壶的。
4.不愿意被微软绑架。这个观点倒是让我感觉到意外,至少我们很多都在用微软的.NET Framework,我们使用微软的SQL Server数据库,如果说我们被绑架,可能现在就已经被绑架了,SQLServer的存储过程跟Oracle、Mysql的存储过程是不一样的,如果将来进行数据库的迁移,那么可想而知后果是怎样的。到底怎样才是真正的被绑架?
5..Net与Java孰好孰坏?
关于这个问题的讨论,一直就是个无休止的讨论。scottgu把这个比作是“带有宗教性质的技术争论”。诚然,讨论这样的问题的确令人讨厌,而且是浪费时间,而且讨论的双方都深切的关注着。讨论来讨论去最终也不会有结果。
在目前所运行的软件系统中,我们可以看到其背后的平台、语言等是各种各样,MySpace是基于.NET平台的,淘宝网是基于Java的,而Google则推崇使用Python,许多大型的电力系统还依然运行在C++平台上,最关键的一点,.NET并不是没有在大型项目中应用。只不过是Java起步早,.NET起步晚而已,要在前几年,Java做的大型项目的确是比.NET的大型项目要多。
很多时候,即使是使用相同的开发语言,不同的程序员开发的程序效率就差30倍以上,甚至几千倍以上,这点好不夸张。诚然,每门技术自有其缺点,但它们也都自有其优点,如果它的优点恰好能符合你的需要,用它就好了。重要的是,你有没有使用好它的能力。
其实总结就不必了,说点题外话吧。存储过程在单条执行操作的时候,的确要比使用ORM要快,可是如果是执行批量的操作,使用存储过程就会非常的费劲。之前我是这样做的。假定更新1000条数据,数据库里只有2个字段,循环调用1000次存储过程需要2分钟左右,当时我把要更新的id以参数的形式逗号分隔传入存储过程,在存储过程中循环执行1000条数据,发现时间跟循环调用1000次存储过程的时间是差不太多的,最终进行了改进,改进的方法嘛,还是把要更新的Id以参数形式逗号分隔传入存储过程,然后使用update table set value=’value’ where id in select id in 分隔函数(id1,id2,id3…..),经过这种方式,更新1000条数据的时间从2分钟变成了200毫秒,可是问题依然不完美,方法存在局限性。
首先,使用这种方法参数的长度是有限制的,varchar类型最大不超过8000,nvarchar类型最大长度不超过4000.
其次,如果表中有多个列,要更新的也是多列,存储过程的局限性就出来了。
再次声明:文中观点仅代表个人观点,如果您有不同意见,欢迎共同讨论。
最后,给大家分享个幽默视频,来缓解下这种紧张而激烈的争论吧。
阅读(...) 评论()数据库的存储过程的有关问题 - Sql Server当前位置:& &&&数据库的存储过程的有关问题数据库的存储过程的有关问题&&网友分享于:&&浏览:4次数据库的存储过程的问题我的存储过程是这样写的:
create & procedure & Pr_AddFile
nvarchar(50),
@Desn &    nvarchar(500),
@Url &    nvarchar(500),
@ParentID nvarchar(50)
insert & into & webfile
(fileid,desn,url,isdel,parentid,creatdate)
(@FileID,@Desn,@Url,@IsDir,@ParentID,GetDate())
消息 & 102,级别 & 15,状态 & 1,过程 & Pr_AddFile,第 & 6 & 行
'  ' & 附近有语法错误。
消息 & 137,级别 & 15,状态 & 2,过程 & Pr_AddFile,第 & 15 & 行
必须声明标量变量 &
&@Desn &。
这是怎么回子事啊,还望高手赐教了!------解决方案--------------------create procedure Pr_AddFile
@FileIDnvarchar(50),
@Desn   nvarchar(500),
@Url   nvarchar(500),
@IsDirint,
@ParentIDnvarchar(50)
------解决方案--------------------注意理解意思,数据类型没分开
create procedure Pr_AddFile
@FileID nvarchar(50),
@Desn nvarchar(500),
@Url nvarchar(500),
@IsDir int,
@ParentID nvarchar(50)
insert into webfile
(fileid,desn,url,isdel,parentid,creatdate)
(@FileID,@Desn,@Url,@IsDir,@ParentID,GetDate())
------解决方案--------------------1 变量名后边空格之后加上变量的类型,每个都得这样写
2 声明部分的变量名应该和使用时候的名称一致
------解决方案--------------------@IsDirint 定义类型 @IsDirint varchar(100),
------解决方案--------------------大哥 你疯了吧 空格呢??
create procedure Pr_AddFile
@FileID nvarchar(50),
@Desn nvarchar(500),
@Url nvarchar(500),
@IsDir int,
@ParentID nvarchar(50)
insert into webfile
(fileid,desn,url,isdel,parentid,creatdate)
(@FileID,@Desn,@Url,@IsDir,@ParentID,GetDate())
------解决方案--------------------create procedure Pr_AddFile
@FileID nvarchar(50),
@Desn nvarchar(500),
@Url nvarchar(500),
@IsDirint nvarchar(500),--没有声明类型
@ParentID nvarchar(50)
insert into webfile
(fileid,desn,url,isdel,parentid,creatdate)
(@FileID,@Desn,@Url,@IsDirint,@ParentID,GetDate())
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有}

我要回帖

更多关于 oracle数据库存储过程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信