存储过程怎么查看执行sql语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和 sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有。
还有一个最大的好处就是利用 sp_executesql,能够重用执行计划,这就大大提供了执行性能,还可以编写更安全的代码。EXEC在某些情况下会更灵活。
除非您有令人信服的理 由使用EXEC,否侧尽量使用sp_*的使用 EXEC命令有两种用法,一种是执行一个存储过程,另一种是执行一个动态的批处理。以下所讲的都是第二种用法。
下面先使用EXEC演示一个例子,代码1 代码 DECLARE @TableName VARCHAR(50),@Sql NVARCHAR (MAX),@OrderID INT; SET @TableName = ‘Orders’; SET @OrderID = 10251; SET @sql = ‘SELECT * FROM ‘+QUOTENAME(@TableName) +’WHERE OrderID = ‘+ CAST(@OrderID AS VARCHAR(10))+’ ORDER BY ORDERID DESC’ EXEC(@sql); 注:这里的EXEC括号中只允许包含一个字符串变量,但是可以串联多个变量,如果我们这样写EXEC:EXEC(‘SELECT TOP(‘+ CAST(@TopCount AS VARCHAR(10)) +’)* FROM ‘+ QUOTENAME(@TableName) +’ ORDER BY ORDERID DESC’); SQL编译器就会报错,编译不通过,而如果我们这样:EXEC(@sql+@sql2+@sql3); 编译器就会通过; 所以最佳的做法是把代码构造到一个变量中,然后再把该变量作为EXEC命令的输入参数,这样就不会受限制了。 EXEC的缺点是不提供接口,这里的接口是指,它不能执行一个包含一个带变量符的批处理,如下 代码 DECLARE @TableName VARCHAR(50),@Sql NVARCHAR(MAX),@OrderID INT; SET @TableName = ‘Orders’; SET @OrderID = 10251; SET @sql = ‘SELECT * FROM ‘+QUOTENAME(@TableName) + ‘WHERE OrderID = @OrderID ORDER BY ORDERID DESC’ EXEC(@sql); 关键就在SET @sql这一句话中,如果我们运行这个批处理,编译器就会产生一下错误 Msg 137, Level 15, State 2, Line 1 必须声明标量变量 “@OrderID”。
使用EXEC时,如果您想访问变量,必须把变量内容串联到动态构建的代码字符串中,如:SET @sql = ‘SELECT * FROM ‘+QUOTENAME(@TableName) + ‘WHERE OrderID = ‘+CAST(@OrderID AS VARCHAR(10))+’ ORDER BY ORDERID DESC’ 串联变量的内容也存在性能方面的弊端。SQL Server为每一个的查询字符串创建新的执行计划,即使查询模式相同也是这样。
为演示这一点,先清空缓存中的执行计划 DBCC FREEPROCCACHE (这个不是本文所涉及的内容,您可以查看MS的MSDN) 将代码1运行3次,分别对@OrderID 赋予下面3个值,10251,10252,10253。然后使用下面的代码查询 SELECT cacheobjtype,objtype,usecounts,sql FROM *heobjects WHERE sql NOT LIKE ‘%cach%’ AND sql NOT LIKE ‘%sys.%’ 点击F5运行,我们可以看到,每执行一次都要产生一次的编译,执行计划没有得到充分重用。
EXEC除了不支持动态批处理中的输入参数外,他也不支持输出参数。默认情况下,EXEC把查询的输出返回给调用者。
例如下面代码返回Orders表中所有的记录数 DECLARE @sql NVARCHAR(MAX) SET @sql = ‘SELECT COUNT(ORDERID) FROM Orders’; EXEC(@sql); 然而,如果你要把输出返回给调用批处理中的变量,事情就没有那么简单了。为此,你必须使用INSERT EXEC语法把输出插入到一个目标表中,然后从这表中获取值后赋给该变量,就像这样:代码 DECLARE @sql NVARCHAR(MAX),@RecordCount INT SET @sql = ‘SELECT COUNT(ORDERID) FROM Orders’; CREATE TABLE #T(TID INT); INSERT INTO #T EXEC(@sql); SET @RecordCount = (SELECT TID FROM #T) SELECT @RecordCount DROP TABLE #*_executesql的使用 sp_executesql命令在SQL Server中引入的比EXEC命令晚一些,它主要为重用执行计划提供更好的支持。
为了和EXEC作一个鲜明的对比,我们看看如果用代码1的代码,把EXEC换成sp_executesql,看看是否得到我们所期望的结果 代码 DECLARE @TableName VARCHAR(50),@sql NVARCHAR(MAX),@OrderID INT ,@sql2 NVARCHAR(MAX); SET @TableName = ‘Orders ‘; SET @OrderID = 10251; SET @sql = ‘SELECT * FROM ‘+QUOTENAME(@TableName) + ‘ WHERE OrderID = ‘+CAST(@OrderID AS VARCHAR(50)) + ‘ ORDER BY ORDERID DESC’ EXEC sp_executesql @sql 注意最后一行;事实证明可以运行;sp_executesql提供接口 sp_executesql命令比EXEC命令更灵活,因为它提供一个接口,该接口及支持输入参数也支持输出参数。这功能使你可以创建带参数的查询字符串,这样就可以比EXEC更好的重用执行计划,sp_executesql的构成与存储过程非常相似,不同之处在于你是动态构建代码。
它的构成包括:代码快,参数声明部分,参数赋值部分。说了这么多,还是看看它的语法:EXEC sp_executesql @stmt=
怎样SQL存储过程中执行动态SQL语句
MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有。
还有一个最大的好处就是利用sp_executesql,能够重用执行计划,这就大大提供了执行性能,还可以编写更安全的代码。EXEC在某些情况下会更灵活。
除非您有令人信服的理由使用EXEC,否侧尽量使用sp_*的使用 EXEC命令有两种用法,一种是执行一个存储过程,另一种是执行一个动态的批处理。以下所讲的都是第二种用法。
下面先使用EXEC演示一个例子,代码1代码 DECLARE @TableName VARCHAR(50),@Sql NVARCHAR (MAX),@OrderID INT; SET @TableName = ‘Orders’; SET @OrderID = 10251; SET @sql = ‘SELECT * FROM ‘+QUOTENAME(@TableName) +’WHERE OrderID = ‘+ CAST(@OrderID AS VARCHAR(10))+’ ORDER BY ORDERID DESC’ EXEC(@sql);注:这里的EXEC括号中只允许包含一个字符串变量,但是可以串联多个变量,如果我们这样写EXEC:EXEC(‘SELECT TOP(‘+ CAST(@TopCount AS VARCHAR(10)) +’)* FROM ‘+ QUOTENAME(@TableName) +’ ORDER BY ORDERID DESC’); SQL编译器就会报错,编译不通过,而如果我们这样:EXEC(@sql+@sql2+@sql3);编译器就会通过; 所以最佳的做法是把代码构造到一个变量中,然后再把该变量作为EXEC命令的输入参数,这样就不会受限制了。 EXEC的缺点是不提供接口,这里的接口是指,它不能执行一个包含一个带变量符的批处理,如下代码 DECLARE @TableName VARCHAR(50),@Sql NVARCHAR(MAX),@OrderID INT; SET @TableName = ‘Orders’; SET @OrderID = 10251; SET @sql = ‘SELECT * FROM ‘+QUOTENAME(@TableName) + ‘WHERE OrderID = @OrderID ORDER BY ORDERID DESC’ EXEC(@sql);关键就在SET @sql这一句话中,如果我们运行这个批处理,编译器就会产生一下错误 Msg 137, Level 15, State 2, Line 1 必须声明标量变量 “@OrderID”。
使用EXEC时,如果您想访问变量,必须把变量内容串联到动态构建的代码字符串中,如:SET @sql = ‘SELECT * FROM ‘+QUOTENAME(@TableName) + ‘WHERE OrderID = ‘+CAST(@OrderID AS VARCHAR(10))+’ ORDER BY ORDERID DESC’串联变量的内容也存在性能方面的弊端。SQL Server为每一个的查询字符串创建新的执行计划,即使查询模式相同也是这样。
为演示这一点,先清空缓存中的执行计划 DBCC FREEPROCCACHE (这个不是本文所涉及的内容,您可以查看MS的MSDN) 将代码1运行3次,分别对@OrderID 赋予下面3个值,10251,10252,10253。然后使用下面的代码查询SELECT cacheobjtype,objtype,usecounts,sql FROM *heobjects WHERE sql NOT LIKE ‘%cach%’ AND sql NOT LIKE ‘%sys.%’ 点击F5运行,我们可以看到,每执行一次都要产生一次的编译,执行计划没有得到充分重用。
EXEC除了不支持动态批处理中的输入参数外,他也不支持输出参数。默认情况下,EXEC把查询的输出返回给调用者。
例如下面代码返回Orders表中所有的记录数DECLARE @sql NVARCHAR(MAX) SET @sql = ‘SELECT COUNT(ORDERID) FROM Orders’; EXEC(@sql);然而,如果你要把输出返回给调用批处理中的变量,事情就没有那么简单了。为此,你必须使用INSERT EXEC语法把输出插入到一个目标表中,然后从这表中获取值后赋给该变量,就像这样:代码DECLARE @sql NVARCHAR(MAX),@RecordCount INT SET @sql = ‘SELECT COUNT(ORDERID) FROM Orders’; CREATE TABLE #T(TID INT); INSERT INTO #T EXEC(@sql); SET @RecordCount = (SELECT TID FROM #T) SELECT @RecordCount DROP TABLE #*_executesql的使用sp_executesql命令在SQL Server中引入的比EXEC命令晚一些,它主要为重用执行计划提供更好的支持。
为了和EXEC作一个鲜明的对比,我们看看如果用代码1的代码,把EXEC换成sp_executesql,看看是否得到我们所期望的结果代码DECLARE @TableName VARCHAR(50),@sql NVARCHAR(MAX),@OrderID INT ,@sql2 NVARCHAR(MAX); SET @TableName = ‘Orders ‘; SET @OrderID = 10251; SET @sql = ‘SELECT * FROM ‘+QUOTENAME(@TableName) + ‘ WHERE OrderID = ‘+CAST(@OrderID AS VARCHAR(50)) + ‘ ORDER BY ORDERID DESC’ EXEC sp_executesql @sql注意最后一行;事实证明可以运行;sp_executesql提供接口sp_executesql命令比EXEC命令更灵活,因为它提供一个接口,该接口及支持输入参数也支持输出参数。这功能使你可以创建带参数的查询字符串,这样就可以比EXEC更好的重用执行计划,sp_executesql的构成与存储过程非常相似,不同之处在于你是动态构建代码。
它的构成包括:代码快,参数声明部分,参数赋值部分。说了这么多,还是看看它的语法:EXEC sp_executesql @stmt=
存储过程与SQL语句是怎样的
我的一位朋友说:他从台湾知名技术作家李维先生的一本书中获悉,如果用存储过程封装SQL语句,系统效率将有极大提升。
他做过实验!!! 我相信朋友做过实验,尽管非亲眼所见。不过我估计他的实验有问题,那样的实验不但蒙蔽了他,也蒙蔽了李维先生(如果他的著作中的内容没有被误会),甚至更多的人。
然而我必须拿出证据,方能使人信服。 后来遇到一个具体的问题:客户端经常要向数据库插入记录。
在J2EE中,一个 Entity Bean Home 的 create 方法调用中,一般就没用存储过程。朋友立马在观点上持反对意见( 可能是因为他暂时有来得及否决J2EE ),认为要是J2EE能够将“插入记录”诸如此类动作改为对存储过程的调用就好了。
我们因此再次发生争论(我仅是反对朋友的看法,但也没提出任何我自己的看法,因为要下一个结论是很不容易的)。最后我不得已而做了实验,分别在 Oracle 10g 和 postgreSQL 8。
0。1 上。
实验内容如下: A、建表脚本: create table ztest( fieldA integer primary key, fieldB varchar(128), fieldC varchar(128) ) B、客户端请求 DBMS 执行的 insert SQL语句: insert into ztest values( ?1, ?2, ?3 ); ?1,?2,?3 将在运行时以合理的值替代之 C、客户端调用的存储过程(JDBC CallableStatement 调用): Oracle:(调用方式 call up_add(。 。
。),) create or replace procedure up_add( fieldA integer, fieldB varchar, fieldC varchar ) is begin insert into ztest values( fieldA, fieldB, fieldC); end; postgreSQL:(客户端调用方式 select uf_add(。
。
) ) CREATE OR REPLACE FUNCTION uf_add (integer, varchar, varchar) RETURNS void AS’ begin insert into ztest values($1,$2,$3); return; end; ‘LANGUAGE ‘plpgsql’ VOLATILE RETURNS NULL ON NULL INPUT SECURITY INVOKER; D、环境: postgreSQL:数据库服务器与客户端程序“都在本机”并“同时运行” Oracle: 独立数据库服务器(测试时始终有人在慢慢打字,应该对机器性能无影响) 测试: 通过不同方式( 即 请求DBMS执行SQL语句 和 调用DBMS逻辑等价的存储过程)向测试表中连续加入 1024 记录 经多次反复测试,得结果如下 postgreSQL: 两种方式下,测试时间均为 21 24 seconds 之间 (每个结果的测试环境一致) Oracle: 8次 SQL 执行请求分别用时(ms) 5422 4750 3875 3812 5672 3531 3484 3547 6次 存储过程调用分别用时(ms) 4578 4500 6297 4219 4547 5734 (每个结果的测试环境一致)由此可知,存储过程封装简单的 SQL 语句,效率相当,且可能更低。 但很多朋友的确得出结论:存储过程的确比SQL快。
为什么? 因为他们测试时写了一个不具实际意义,同时也与SQL语句的“一次客户端调用”不具可比性的测试用存储过程。Oracle PL/SQL 描述方式如下,该方法一次调用就可以向数据表添加 1024 条记录,连网络通讯都省了。
怪不得性能有“千倍差异”! create or replace procedure up_add( ) is declare n:integer; begin n := 0; while( n 它与客户端一次提交单条 SQL 语句没有可比性:当一次只需要向DBMS提交一条新记录,要这个存储过程干什么呢?。
怎样SQL存储过程中执行动态SQL语句
*的使用
EXEC命令有两种用法,一种是执行一个存储过程,另一种是执行一个动态的批处理。以下所讲的都是第二种用法。
下面先使用EXEC演示一个例子,代码1
DECLARE @TableName VARCHAR(50),@Sql NVARCHAR (MAX),@OrderID INT;
SET @TableName = ‘Orders’;
SET @OrderID = 10251;
SET @sql =
‘SELECT * FROM ‘+QUOTENAME(@TableName) +’WHERE OrderID = ‘+
CAST(@OrderID AS VARCHAR(10))+’ ORDER BY ORDERID DESC’
EXEC(@sql);
sp_executesql命令在SQL Server中引入的比EXEC命令晚一些,它主要为重用执行计划提供更好的支持。
为了和EXEC作一个鲜明的对比,我们看看如果用代码1的代码,把EXEC换成sp_executesql,看看是否得到我们所期望的结果
DECLARE @TableName VARCHAR(50),@sql NVARCHAR(MAX),@OrderID INT ,@sql2 NVARCHAR(MAX);
SET @TableName = ‘Orders ‘;
SET @OrderID = 10251;
SET @sql = ‘SELECT * FROM ‘+QUOTENAME(@TableName) + ‘ WHERE OrderID = ‘+CAST(@OrderID AS VARCHAR(50)) + ‘ ORDER BY ORDERID DESC’
EXEC sp_executesql @sql
使用SQL语句创建存储过程
使用SQL语句创建存储的具体过程如下:
1、首先,打开企业管理器,选择【工具】【查询分析器】:
2、然后,输入SQL语句。如下:
CREATE PROCEDURE byroyalty1 @percentage int
AS
select au_id from titleauthor
where *yper = @percentage
GO
3、然后,点击确定之后,命令就会自动添加进查询中:
4、然后执行一下刚输入的命令:
5、最后,就可以在弹出的小窗口中查看存储过程了:
数据库存储过程是在sql语句下执行的吗
一般分为十种情况,每种语法各不相同:
1、 创建语法
create proc | procedure pro_name
[{@参数数据类型} [=默认值] [output],
{@参数数据类型} [=默认值] [output],
。.
]
as
SQL_statements
2、 创建不带参数存储过程
创建存储过程
if (exists (select * from *s where name = ‘proc_get_student’))
drop proc proc_get_student
go
create proc proc_get_student
as
select * from student;
调用、执行存储过程
exec proc_get_student;
3、 修改存储过程
修改存储过程
alter proc proc_get_student
as
select * from student;
4、 带参存储过程
带参存储过程
if (object_id(‘proc_find_stu’, ‘P’) is not null)
drop proc proc_find_stu
go