存储过程与SQL语句的恩怨情仇
程序员说:存储过程还是SQL语句,这是一个问题。 江湖现在有三个流派,一个是SQL语句流的,崇尚使用SQL语句,一派是存储过程派的,崇尚用存储过程说话,还有一派是中庸派的,讲求和谐,所以也就前两派吵得厉害,中庸派的看热闹。
现在SQL派的有Nhibernate为首的众多ORM助阵,最近风生水起比较得意,存储过程派也有自己的杀手秘籍,两派互不相让,争斗由来已久。 存储过程派的追求速度,所谓天下无功无坚不破,唯快不破,这也是存储过程派的人行走江湖的最大本钱。
之前存储过程派的攻击SQL语句派的还有一个秘籍就是安全,不过现在都没人用连接String的动态SQL的了,这招也就失效了。 SQL语句派是资格很老的流派,但是新手居多,老资格很多投奔敌营存储过程派了。Java帮的人很多都是SQL语句派的,而存储过程派的以微软帮的居多。
不过存储过程派也有软肋,可移植性就是其一,还有一点就是可扩展性,因为一般大型的Web应用程序都是多Web服务器,然后用双数据库服务器做双机热备,其中一台开机,但是是闲置的,这里只是解决单点故障的问题,但是形成了多Web应用服务器,单数据库服务器的情况,如果所有的运算都用存储过程实现,那么会造成数据库服务器负担过重,而Web服务器负荷不足的情况,而扩展数据库服务器的话就会非常的麻烦,而且投资较大,程序也需要改,而投资Web服务器就相对便宜而且扩容更加简单。
人在江湖漂哪有不挨刀,所以中庸一点比较保险,我比较倾向于用把较多的负担放到程序里来,而降低数据库得负担,因为只要数据库扛得住,再增加Web服务器那是比较容易的,但是一旦数据库服务器扛不住了我们就只有哭了。一般报表阿,还有一些结果集比较复杂的我就用存储过程来包装,一般的查询和CUID操作我都是找个ORM来搞定。 其实主要是在说存储过程的软肋。
1)从部署上看,存储过程要比sql难
2) 从性能看,存储过程要比SQL高
3) 从安全性将,存储过程比SQL防注入 过程可以减少网络数据传输量,把计算都放在服务器上 前端程序可以直接访问数据库的表,可以直接用SQL语言直接对数据库的表进行读写操作; 为安全,可以编程,使用存储过程进行数据表的读写操作,而前端程序直接访问这些存储过程,而不是数据库的表; 更安全的方法是:在前端程序和数据库之间,增加数据库访问层;前端将数据的读写请求提交给中间层,有中间层与数据库连接进行数据库的实际操作,将结果送给前端,这种方式可以避免前端机器直接连接到数据库的可能,数据库更安全。
C#两种不同的存储过程调用方法 ====================================================
两种不同的存储过程调用方法 为了突出新方法的优点,首先介绍一下在.NET中调用存储过程的“官方”方法。另外,本文的所有示例程序均工作于SqlServer数据库上,其它情况类似,以后不再一一说明。本文所有例子均采用C#语言。 要在应用程序中访问数据库,一般性的步骤是:首先声明一个数据库连接SqlConnection,然后声明一个数据库命令SqlCommand,用来执行 SQL语句和存储过程。有了这两个对象后,就可以根据自己的需要采用不同的执行方式达到目的。需要补充的是,不要忘记在页面上添加如下的引用语句: using System.Data.SqlClient。 就执行存储过程来说,如果执行的是第一类存储过程,那么就要用一个
DataAdapter将结果填充到一个DataSet中,然后就可以使用数据网格控件将结果呈现在页面上了;如果执行的是第二和第三种存储过程,则不需要此过程,只需要根据特定的返回判定操作是否成功完成即可。
<!--[if !supportLists]-->(1)
<!--[endif]-->执行一个没有参数的存储过程的代码如下:
SqlConnection conn=new
SqlConnection(“connectionString”);
SqlDataAdapter da = new
SqlDataAdapter();
da.SelectCommand = new SqlCommand();
da.SelectCommand.Connection =
conn;
da.SelectCommand.CommandText =
"NameOfProcedure"; da.SelectCommand.CommandType =
CommandType.StoredProcedure;
然后只要选择适当的方式执行此处过程,用于不同的目的即可。
<!--[if !supportLists]-->(2)
<!--[endif]-->执行一个有参数的存储过程的代码如下(我们可以将调用存储过程的函数声明为ExeProcedure(string inputdate)): SqlConnection conn=new SqlConnection(“connectionString”);
SqlDataAdapter da = new SqlDataAdapter(); da.SelectCommand = new SqlCommand();
da.SelectCommand.Connection = conn; da.SelectCommand.CommandText =
"NameOfProcedure"; da.SelectCommand.CommandType =
CommandType.StoredProcedure; (以上代码相同,以下为要添加的代码)
param = new
SqlParameter("@ParameterName", SqlDbType.DateTime); param.Direction =
ParameterDirection.Input; param.Value = Convert.ToDateTime(inputdate);
da.SelectCommand.Parameters.Add(param);
这样就添加了一个输入参数。若需要添加输出参数:
param = new
SqlParameter("@ParameterName", SqlDbType.DateTime); param.Direction =
ParameterDirection.Output; param.Value = Convert.ToDateTime(inputdate);
da.SelectCommand.Parameters.Add(param); 若要获得参储过程的返回值:
param = new
SqlParameter("@ParameterName", SqlDbType.DateTime); param.Direction =
ParameterDirection.ReturnValue;
param.Value =
Convert.ToDateTime(inputdate); da.SelectCommand.Parameters.Add(param);
从上面的代码我们可以看出,当存储过程比较多或者存储过程的参数比较多时,这种方法会大大影响开发的速度;另外一方面,如果项目比较大,那么这些用于数据库逻辑的函数在以后的维护中也是一个很大的负担。那么,有没有一种改进的方法可以解决这个问题呢?想到在执行没有参数的存储过程时只需要传入一个存储过程的名字就可以调用相应的存储过程,而且在SqlServer数据库中我们可以直接在查询分析器中敲入“存储过程名(参数列表)”样的字符串就可以执行存储过程,那么,是否可以把这种思想应用到应用程序中呢?
于是在编译器中键入相应代码。这些代码是在调用不带参数的存储过程的代码的基础上改的。具体代码如下:
SqlConnection conn=new SqlConnection(“connectionString”);
SqlDataAdapter da = new
SqlDataAdapter();
da.SelectCommand = new SqlCommand();
da.SelectCommand.Connection = conn;
da.SelectCommand.CommandText = "NameOfProcedure(’para1’,’para2’,para3)";
da.SelectCommand.CommandType = CommandType.StoredProcedure;
为了使代码更具有代表性,要调用的存储过程的第一个和第二个参数都为字符串类型,第三个参数为整型。执行以后发现,完全可以达到预期的效果! SQL Server 2005帮助文档中关于存储过程返回值使用的例子和说明 RETURN 语句无条件终止查询、存储过程或批处理。存储过程或批处理中 RETURN 语句后面的语句都不执行。 当在存储过程中使用 RETURN 语句时,此语句可以指定返回给调用应用程序、批处理或过程的整数值。如果 RETURN 未指定值,则存储过程返回 0。 大多数存储过程按常规使用返回代码表示存储过程的成功或失败。没有发生错误时存储过程返回值 0。任何非零值表示有错误发生。例如:
USE AdventureWorks; GO --
Create a procedure that takes one input parameter -- and returns one output
parameter and a return code. CREATE PROCEDURE SampleProcedure @EmployeeIDParm
INT, @MaxTotal INT OUTPUT AS -- Declare and initialize a variable to hold
@@ERROR. DECLARE @ErrorSave int; SET @ErrorSave = 0; -- Do a SELECT using the
input parameter. SELECT c.FirstName, c.LastName, e.Title FROM HumanResources.Employee
AS e JOIN Person.Contact AS c ON e.ContactID = c.ContactID WHERE EmployeeID =
@EmployeeIDParm; -- Save any nonzero @@ERROR value. IF (@@ERROR 0) SET
@ErrorSave = @@ERROR; -- Set a value in the output parameter. SELECT @MaxTotal
= MAX(TotalDue) FROM Sales.SalesOrderHeader; IF (@@ERROR 0) SET @ErrorSave =
@@ERROR; -- Returns 0 if neither SELECT statement had -- an error, otherwise
returns the last error. RETURN @ErrorSave; GO 执行存储过程的 Transact-SQL 批处理或存储过程可以将返回代码检索到整数变量中: DECLARE @ReturnStatus int; DECLARE @MaxTotalVariable int; DECLARE
@MaxTotal int; EXECUTE @ReturnStatus = SampleProcedure @EmployeeIDParm = 65
,@MaxTotal = @MaxTotalVariable OUTPUT; PRINT ' '; PRINT 'Return code = ' +
CAST(@ReturnStatus AS CHAR(10)); PRINT 'Maximum Order Total = ' +
CAST(@MaxTotalVariable AS CHAR(15)); GO 调用存储过程的应用程序可以将返回代码所对应的参数标记与整型变量绑定。
分享到:
相关推荐
内容概要:简单的C# winform调用存储过程实例,创建存储过程入参,通过SqlConnection对象和SqlCommand对象调用存储过程,获取存储过程的出参并显示出来,详细代码注释,希望对用到C#调用存储过程的小伙伴有帮助 ...
在 SQL Server 中,存储过程比直接运行 SQL 语句慢的原因是 Parameter sniffing 问题。Parameter sniffing 是指 SQL Server 在执行存储过程时,使用参数的统计信息来优化执行计划,但这种优化方式有时可能会导致执行...
总的来说,将C#的Lambda表达式转换为SQL语句是一项复杂但非常实用的任务,它使我们能够在不离开C#环境的情况下编写复杂的数据库查询,同时保持代码的清晰和简洁。这种技术对于开发高效、灵活的ORM(对象关系映射)...
### C#调用Oracle方法(包括调用存储过程) 在.NET框架中,使用C#语言进行数据库操作是一项常见的任务。本文将详细介绍如何使用C#语言连接Oracle数据库,并演示如何调用Oracle存储过程,特别是带有输出参数的情况。...
### C#中SQL语句调用详解 在.NET框架中,使用C#语言与SQL Server进行交互是非常常见的操作。本文将详细介绍如何在C#应用程序中编写SQL语句,并通过ADO.NET来执行这些语句。 #### ADO.NET简介 ADO.NET(ActiveX ...
在C#中调用Oracle存储过程来返回数据集是一个常见的任务,这涉及到ADO.NET库的使用,特别是OracleClient组件。Oracle存储过程是数据库中的预编译SQL代码块,可以接收输入参数,执行复杂的业务逻辑,并返回结果。在C#...
存储过程是在数据库端预编译的SQL代码集合,可以在C#中调用,减少了网络传输和解析SQL的成本。ADO.NET虽然直接操作数据库,但可以通过Command对象执行预定义的存储过程,而不需要手动编写SQL。 总结来说,C#中不写...
2. 使用Entity Framework:如果你的项目使用了ORM框架,如Entity Framework,那么可以通过DbContext的DbSet对象的SqlQuery方法或DbDatabase的ExecuteSqlCommand方法调用存储过程。 ```csharp using (var context = ...
存储过程是预编译的SQL语句集合,可以在数据库端执行复杂的业务逻辑,提高性能并减少网络通信。本文将详细讲解如何在C#中调用SQL存储过程,并提供相关的实践指导。 1. **C#与SQL Server的连接** 在C#中,我们通常...
"C#调用分页存储过程"是一个常见的技术实践,它结合了C#编程语言和SQL Server的存储过程来高效地获取数据库中的分页数据。这种方法可以有效地减少网络传输的数据量,提高用户界面的响应速度,尤其是在数据量达到百万...
在数据库操作中,存储过程是一个预编译的SQL语句集合,它可以在数据库服务器上执行,提高了执行效率并提供了封装和重用的能力。本篇将详细讨论如何在C#中调用含参存储过程。 首先,我们来看存储过程的创建。在SQL ...
在IT领域,特别是软件开发与数据库交互中,C#作为一种广泛使用的编程语言,其与数据库的交互能力尤为重要。...无论是在企业级应用还是小型项目中,熟练运用C#调用存储过程的能力都是提升程序性能和安全性的关键。
在C#中,利用泛型和反射可以创建灵活的数据库操作库,自动根据实体类生成对应的SQL语句。例如,我们可以定义一个泛型方法,接受一个类型参数,这个类型对应于数据库表的实体模型: ```csharp public void Save(T ...
C#连接数据库,执行SQL语句和存储过程的代码,封装好了的,直接调用就可以
### C#中调用Oracle存储过程 ...4. **参数验证**:在调用存储过程前,应对传入的参数进行必要的验证,防止注入攻击。 通过以上步骤和注意事项,可以有效地在C#中调用Oracle存储过程,实现复杂业务逻辑的高效处理。
在C#中,我们可以使用ADO.NET(.NET Framework的一部分)来调用存储过程。ADO.NET提供了一套全面的类库,用于与各种数据库进行交互,如SqlConnection、SqlCommand等。以下是一个基本的步骤: 1. **创建数据库连接**...
调用存储过程通常比直接执行SQL语句更快,因为它减少了网络通信次数,因为存储过程是在数据库服务器上预编译的。此外,存储过程还可以缓存执行计划,进一步提升性能。 总的来说,C#调用SQL Server存储过程是通过`...
总的来说,C#调用存储过程涉及建立数据库连接、创建命令对象、设置参数、执行存储过程和处理返回结果等步骤。理解这些步骤对于任何需要与数据库交互的C#开发者都至关重要。在实际项目中,你可能会遇到更复杂的情况,...
首先,存储过程(Stored Procedure)是预编译的SQL语句集合,存储在数据库中并可重复调用。它们提高了代码的执行效率,增强了安全性,并允许数据库管理员控制访问权限。在SQL Server 2005中,存储过程可以接收输入...