进的人多少都有分

dengNeeo 2010-09-14 01:38:37
alter proc ProductSearch
(
@type nvarchar(50),
@KeyWord nvarchar(255)
)
as
EXEC('select *,bookcost*bookRebate as Nowcost from book where '+ @type+' like ''%'+ @KeyWord+'%''')
go
为什么存储过程要用EXEC
什么情况下才用EXEC
说明理由 重分奖赏 顶者1分
...全文
293 54 打赏 收藏 转发到动态 举报
写回复
用AI写文章
54 条回复
切换为时间正序
请发表友善的回复…
发表回复
wang137221103 2010-09-14
  • 打赏
  • 举报
回复
还有么
HolyPlace 2010-09-14
  • 打赏
  • 举报
回复
EXEC 执行存储过程或者动态sql

现在都超过50楼了,你也就50分,你看这办吧。。。。。
jxmlearner 2010-09-14
  • 打赏
  • 举报
回复
有人说这样也可以
AS
select *,bookcost*bookRebate as Nowcost from book where @type like '''%'+ @KeyWord+'%'''
GO

你可以去验证下看,呵呵!
huangmin3956 2010-09-14
  • 打赏
  • 举报
回复
拿一分走人 嘎嘎
qazwsy 2010-09-14
  • 打赏
  • 举报
回复
虽然我不懂但是我想要分
jxmlearner 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用楼主 rewoshengqi 的回复:]
alter proc ProductSearch
(
@type nvarchar(50),
@KeyWord nvarchar(255)
)
as
EXEC('select *,bookcost*bookRebate as Nowcost from book where '+ @type+' like ''%'+ @KeyWord+'%''')
go
为什么存储过……
[/Quote]
同楼主有一样的疑惑,只知道有模糊查询的时候就要写成 EXEC(@sql)的形式,不然存储过程查不到,
添加删除修改那些都可以不用,当然用也可以,
为什么我也不知道.
dongist 2010-09-14
  • 打赏
  • 举报
回复
刚注册,顶
村长_乐 2010-09-14
  • 打赏
  • 举报
回复
SQLSERVER 动态执行SQL sp_executesql与EXEC
摘自SQL server帮助文档
对大家优查询速度有帮助!


建议使用 sp_executesql 而不要使用 EXECUTE 语句执行字符串。支持参数替换不仅使 sp_executesql 比 EXECUTE 更通用,而且还使 sp_executesql 更有效,因为它生成的执行计划更有可能被 SQL Server 重新使用。

自包含批处理
sp_executesql 或 EXECUTE 语句执行字符串时,字符串被作为其自包含批处理执行。SQL Server 将Transact-SQL 语句或字符串中的语句编译进一个执行计划,该执行计划独立于包含 sp_executesql 或 EXECUTE 语句的批处理的执行计划。下列规则适用于自含的批处理:

直到执行 sp_executesql 或EXECUTE 语句时才将sp_executesql 或 EXECUTE 字符串中的 Transact-SQL 语句编译进执行计划。执行字符串时才开始分析或检查其错误。执行时才对字符串中引用的名称进行解析。


执行的字符串中的 Transact-SQL 语句,不能访问 sp_executesql 或 EXECUTE 语句所在批处理中声明的任何变量。包含 sp_executesql 或 EXECUTE 语句的批处理不能访问执行的字符串中定义的变量或局部游标。


如果执行字符串有更改数据库上下文的 USE 语句,则对数据库上下文的更改仅持续到 sp_executesql 或 EXECUTE 语句完成。
通过执行下列两个批处理来举例说明:

/* Show not having access to variables from the calling batch. */
DECLARE @CharVariable CHAR(3)
SET @CharVariable = 'abc'
/* sp_executesql fails because @CharVariable has gone out of scope. */
sp_executesql N'PRINT @CharVariable'
GO

/* Show database context resetting after sp_executesql completes. */
USE pubs
GO
sp_executesql N'USE Northwind'
GO
/* This statement fails because the database context
has now returned to pubs. */
SELECT * FROM Shippers
GO

替换参数值
sp_executesql 支持对 Transact-SQL 字符串中指定的任何参数的参数值进行替换,但是 EXECUTE 语句不支持。因此,由 sp_executesql 生成的 Transact-SQL 字符串比由 EXECUTE 语句所生成的更相似。SQL Server 查询优化器可能将来自 sp_executesql 的 Transact-SQL 语句与以前所执行的语句的执行计划相匹配,以节约编译新的执行计划的开销。

使用 EXECUTE 语句时,必须将所有参数值转换为字符或 Unicode 并使其成为 Transact-SQL 字符串的一部分:

DECLARE @IntVariable INT
DECLARE @SQLString NVARCHAR(500)
/* Build and execute a string with one parameter value. */
SET @IntVariable = 35
SET @SQLString = N'SELECT * FROM pubs.dbo.employee WHERE job_lvl = ' +
CAST(@IntVariable AS NVARCHAR(10))
EXEC(@SQLString)
/* Build and execute a string with a second parameter value. */
SET @IntVariable = 201
SET @SQLString = N'SELECT * FROM pubs.dbo.employee WHERE job_lvl = ' +
CAST(@IntVariable AS NVARCHAR(10))
EXEC(@SQLString)

如果语句重复执行,则即使仅有的区别是为参数所提供的值不同,每次执行时也必须生成全新的 Transact-SQL 字符串。从而在下面几个方面产生额外的开销:

SQL Server 查询优化器具有将新的 Transact-SQL 字符串与现有的执行计划匹配的能力,此能力被字符串文本中不断更改的参数值妨碍,特别是在复杂的 Transact-SQL 语句中。


每次执行时均必须重新生成整个字符串。


每次执行时必须将参数值(不是字符或 Unicode 值)投影到字符或 Unicode 格式。
sp_executesql 支持与 Transact-SQL 字符串相独立的参数值的设置:

DECLARE @IntVariable INT
DECLARE @SQLString NVARCHAR(500)
DECLARE @ParmDefinition NVARCHAR(500)

/* Build the SQL string once. */
SET @SQLString =
N'SELECT * FROM pubs.dbo.employee WHERE job_lvl = @level'
/* Specify the parameter format once. */
SET @ParmDefinition = N'@level tinyint'

/* Execute the string with the first parameter value. */
SET @IntVariable = 35
EXECUTE sp_executesql @SQLString, @ParmDefinition,
@level = @IntVariable
/* Execute the same string with the second parameter value. */
SET @IntVariable = 32
EXECUTE sp_executesql @SQLString, @ParmDefinition,
@level = @IntVariable

此 sp_executesql 示例完成的任务与前面的 EXECUTE 示例所完成的相同,但有下列额外优点:

因为 Transact-SQL 语句的实际文本在两次执行之间未改变,所以查询优化器应该能将第二次执行中的 Transact-SQL 语句与第一次执行时生成的执行计划匹配。这样,SQL Server 不必编译第二条语句。


Transact-SQL 字符串只生成一次。


整型参数按其本身格式指定。不需要转换为 Unicode。


说明 为了使 SQL Server 重新使用执行计划,语句字符串中的对象名称必须完全符合要求。


重新使用执行计划
在 SQL Server 早期的版本中要重新使用执行计划的唯一方式是,将 Transact-SQL 语句定义为存储过程然后使应用程序执行此存储过程。这就产生了管理应用程序的额外开销。使用 sp_executesql 有助于减少此开销,并使 SQL Server 得以重新使用执行计划。当要多次执行某个 Transact-SQL 语句,且唯一的变化是提供给该 Transact-SQL 语句的参数值时,可以使用 sp_executesql 来代替存储过程。因为 Transact-SQL 语句本身保持不变仅参数值变化,所以 SQL Server 查询优化器可能重复使用首次执行时所生成的执行计划。

下例为服务器上除四个系统数据库之外的每个数据库生成并执行 DBCC CHECKDB 语句:

USE master
GO
SET NOCOUNT ON
GO
DECLARE AllDatabases CURSOR FOR
SELECT name FROM sysdatabases WHERE dbid > 4

OPEN AllDatabases

DECLARE @DBNameVar NVARCHAR(128)
DECLARE @Statement NVARCHAR(300)

FETCH NEXT FROM AllDatabases INTO @DBNameVar
WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT N'CHECKING DATABASE ' + @DBNameVar
SET @Statement = N'USE ' + @DBNameVar + CHAR(13)
+ N'DBCC CHECKDB (' + @DBNameVar + N')'
EXEC sp_executesql @Statement
PRINT CHAR(13) + CHAR(13)
FETCH NEXT FROM AllDatabases INTO @DBNameVar
END

CLOSE AllDatabases
DEALLOCATE AllDatabases
GO
SET NOCOUNT OFF
GO

当目前所执行的 Transact-SQL 语句包含绑定参数标记时,SQL Server ODBC 驱动程序使用 sp_executesql 完成 SQLExecDirect。但例外情况是 sp_executesql 不用于执行中的数据参数。这使得使用标准 ODBC 函数或使用在 ODBC 上定义的 API(如 RDO)的应用程序得以利用 sp_executesql 所提供的优势。定位于 SQL Server 2000 的现有的 ODBC 应用程序不需要重写就可以自动获得性能增益。有关更多信息,请参见使用语句参数。

用于 SQL Server 的 Microsoft OLE DB 提供程序也使用 sp_executesql 直接执行带有绑定参数的语句。使用 OLE DB 或 ADO 的应用程序不必重写就可以获得 sp_executesql 所提供的优势。
来自http://topic.csdn.net/u/20080610/12/9b4100e7-66b9-47dd-8cb3-39ebb76fe4fc.html
lala19 2010-09-14
  • 打赏
  • 举报
回复
新手~ 初级阶段~ 一样求解···
dengNeeo 2010-09-14
  • 打赏
  • 举报
回复
存储过程的like和execSql 2007-05-15 13:13:26 阅读343 评论0 字号:大中小 订阅
create proc ProductSearch
(
@type nvarchar(50),
@KeyWord nvarchar(255)
)
as
select *,bookcost*bookRebate as Nowcost from book where @type like '%'+@KeyWord+'%'
go

有如上的存储过程,当我输入
exec ProductSearch 'bookname','c'
即查询 书名中包含c关键字的图书。
以上语句怎么查出来的老是空的呀。

要是单独放出来查询就可以了
select *,bookcost*bookRebate as Nowcost from book where bookname like '%c%'。

但是我用如下存储过程就可以了:

alter proc ProductSearch
(
@type nvarchar(50),
@KeyWord nvarchar(255)
)
as
EXEC('select *,bookcost*bookRebate as Nowcost from book where '+ @type+' like ''%'+ @KeyWord+'%''')
go

我要的是解释为什么要加exec,从csdn论坛得到别人的回答是:

对于字段不能直接使用参数,这个是 sql server解析原理 决定的。

我好象明白了一点点,因为@type传进来的是字段,所以不能直接作为参数。

同时我又获得了另外一个人给我的解释:

create proc ProductSearch
@type nvarchar(50),
@KeyWord nvarchar(255)
as
declare @sql varchar(8000)
set
@sql='select *,bookcost*bookRebate as Nowcost from book where '+ @type+' like ''%'+ @KeyWord+'%'''
exec (@sql)
GO
于是我对我以前做过的普通的不包含把字段作为参数的存储过程也写为上面那种形式,发现



--存储过程查询各类书

方法一:
alter proc BookByCategory
(
@categoryID int
)
as
select BookID,BookName,BookAuthor,BookCost,BookImage,BookTime,BookPublisher,BookIsbn,bookcost*bookrebate as Nowcost,bookrebate
from book
where categoryID=@categoryID
go

方法二:
alter proc BookByCategory
(
@categoryID char(10)
)
as
declare @sql varchar(8000)
set
@sql='select BookID,BookName,BookAuthor,BookCost,BookImage,BookTime,BookPublisher,BookIsbn,bookcost*bookrebate as Nowcost,bookrebate
from book
where categoryID='+@categoryID
exec(@sql)
go

exec BookByCategory 1

exec BookByCategory ‘1’

发现其实所有的存储过程都可以写成类似与方法二的写法。同时还发现对与数字,在sql中可以自动解析为int类型或char类型,所以传进来的参数不管是1或者‘1’。都可获取查询结果。

其实存储过程中省略了exec,因为所有的存储过程都可以用

create proc pro_name

@test1 type,

@test2 type

as

exec(字符串)

go

只是当遇到列名做为参数的时候exec不能省略

dengNeeo 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 newdigitime 的回复:]
引用楼主 rewoshengqi 的回复:
为什么存储过程要用EXEC
很简单,因为你的存储中要执行"动态的SQL语句",所以就用上exec了.
如果是固定的SQL语句,就没必要用EXEC
[/Quote]

可是有的时候动态不用也行呀
yoyo_ 2010-09-14
  • 打赏
  • 举报
回复
存储过程是预编译的吧 调用的时候直接不用重新编译的,
使用exec 来调用已编译的
liyangyang621726 2010-09-14
  • 打赏
  • 举报
回复
exec 使用来调用已编译的
andylei0145 2010-09-14
  • 打赏
  • 举报
回复
在查询分析器中执行都要用exec,我帮顶
sunny_yu 2010-09-14
  • 打赏
  • 举报
回复
alter proc ProductSearch
(
@type nvarchar(50),
@KeyWord nvarchar(255)
)
as
EXEC('select *,bookcost*bookRebate as Nowcost from book where '+ @type+' like ''%'+ @KeyWord+'%''')
go

alter proc ProductSearch
(
@type nvarchar(50),
@KeyWord nvarchar(255)
)
as
select *,bookcost*bookRebate as Nowcost from book where type like '%'+ @KeyWord+'%'
go

huangwenquan123 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 huangwenquan123 的回复:]
如果只是一句sql语句!没有动态拼接或什么的
例如
create proc zz
as
select * from table
这样就不用esec

create proc zz
(
@ID int
)
declare @Sql varchar(200)
set @Sql = 'select * from table where ID='+@ID+''
esec(@……
[/Quote]这里只是个举例!当然直接写成select * from table where ID=@ID就可以!
huangwenquan123 2010-09-14
  • 打赏
  • 举报
回复
如果只是一句sql语句!没有动态拼接或什么的
例如
create proc zz
as
select * from table
这样就不用esec

create proc zz
(
@ID int
)
declare @Sql varchar(200)
set @Sql = 'select * from table where ID='+@ID+''
esec(@Sql);
这时就要用esec
辰爸 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用楼主 rewoshengqi 的回复:]
alter proc ProductSearch
(
@type nvarchar(50),
@KeyWord nvarchar(255)
)
as
EXEC('select *,bookcost*bookRebate as Nowcost from book where '+ @type+' like ''%'+ @KeyWord+'%''')
go
为什么存……
[/Quote]
动态执行语句的时候需要使用Exec
newdigitime 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用楼主 rewoshengqi 的回复:]
为什么存储过程要用EXEC[/Quote]
很简单,因为你的存储中要执行"动态的SQL语句",所以就用上exec了.
如果是固定的SQL语句,就没必要用EXEC
dengNeeo 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 xuzhefengchen 的回复:]
哇靠,你分给到俄罗斯了……
[/Quote]
什么意思
加载更多回复(24)

62,272

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧