exec执行sql语句有限制,如何突破这个限制?

事理 2014-04-22 12:22:26
一个分页存储过程,部分代码如下,发现当里面拼接的sql语句过长后,导致无法执行
我删除部分sql语句后,就可以执行,请问那位大神有遇到过这种问题,是如何解决这个问题的?
网上查找了下,参考http://www.cnblogs.com/RascallySnake/archive/2010/05/20/1739839.html里面的,问题还是依旧。

declare @sql1 varchar(200)
set @sql1='SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY '
declare @sql2 varchar(50)
set @sql2=') AS rownumber,'
declare @sql3 varchar(10)
set @sql3=' FROM '
declare @sql4 varchar(100)
set @sql4=') AS tempdt WHERE rownumber BETWEEN '+@startRow+' AND '+@endRow

/*执行查询语句,返回查询结果*/
exec
(
@sql1+@OrderBy+@sql2+@Fields+@sql3+@Table+@Where+@sql4
)
...全文
489 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
事理 2014-04-23
  • 打赏
  • 举报
回复
问题其实和这个一样,但是到文章最后也没给出解决办法 http://stackoverflow.com/questions/17095924/error-with-dynamic-sql-statement-cutting-off-with-exec-command
xdashewan 2014-04-23
  • 打赏
  • 举报
回复
你先看你除了分页的那段语句能用exec吗
事理 2014-04-23
  • 打赏
  • 举报
回复
sql语句过长就会出现这种问题,我也想插入到临时表,现在关键是拼接的sql语句得不到执行
xdashewan 2014-04-23
  • 打赏
  • 举报
回复
同类型分页一直用的好好的,没发生此类问题,实在不行,把你分页里面的数据先插入个表变量或者零时表,再对表变量或者零时表进行分页
事理 2014-04-23
  • 打赏
  • 举报
回复
引用 10 楼 rockyljt 的回复:
如果可能,数据库升级到sql 2008就解决了
Sql2008问题依旧,难道这个是无解的问题吗?
叶子 2014-04-23
  • 打赏
  • 举报
回复
打印出来只有1476,根本就不长,执行不了只因为这1476又被截断了。
引用 6 楼 slyzly 的回复:
打印出来的长度也只有 1476 打印出来的sql测试语句如下 SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY UserName) AS rownumber,UserId,UserName,RealName,IdentificationCard,Telphone,HomePhone,Email,LastLoginTime,UserStateId,LoginTotalCount FROM SL_User WHERE InTheRecycleBin=0 and (charindex(','+'60'+',',','+ClassIds+',')>0 or charindex(','+'61'+',',','+ClassIds+',')>0 or charindex(','+'62'+',',','+ClassIds+',')>0 or charindex(','+'63'+',',','+ClassIds+',')>0 or charindex(','+'64'+',',','+ClassIds+',')>0 or charindex(','+'65'+',',','+ClassIds+',')>0 or charindex(','+'66'+',',','+ClassIds+',')>0 or charindex(','+'77'+',',','+ClassIds+',')>0 or charindex(','+'78'+',',','+ClassIds+',')>0 or charindex(','+'79'+',',','+ClassIds+',')>0 or charindex(','+'80'+',',','+ClassIds+',')>0 or charindex(','+'81'+',',','+ClassIds+',')>0 or charindex(','+'82'+',',','+ClassIds+',')>0 or charindex(','+'83'+',',','+ClassIds+',')>0 or charindex(','+'84'+',',','+ClassIds+',')>0 or charindex(','+'85'+',',','+ClassIds+',')>0 or charindex(','+'86'+',',','+ClassIds+',')>0 or charindex(','+'87'+',',','+ClassIds+',')>0 or charindex(','+'88'+',',','+ClassIds+',')>0 or charindex(','+'89'+',',','+ClassIds+',')>0 or charindex(','+'90'+',',','+ClassIds+',')>0 or charindex(','+'91'+',',','+ClassIds+',')>0 or charindex(','+'92'+',',','+ClassIds+',')>0 or charindex(','+'93'+',',','+ClassIds+',')>0) and userid=201 and userid=482 and userid=483 and userid=488 and userid=530 and userid=531 and userid=532) AS tempdt WHERE rownumber BETWEEN 1 AND 20
事理 2014-04-23
  • 打赏
  • 举报
回复
你真是天才,还真是后面的问题,where条件太长了,其实是后面出现了错误,纠结老半天,哈哈。
sdhp 2014-04-23
  • 打赏
  • 举报
回复
引用 21 楼 slyzly 的回复:
[quote=引用 20 楼 sdhp 的回复:] 应该是你最后这里: declare @strsql nvarchar(1200) set @strsql='SELECT @i=COUNT(*) FROM '+@Table+@Where execute sp_executesql @strsql,N'@i int out',@Count OUT--返回总记录数 你定义的@strsql只有1200吧,改成nvarchar(max)看看
真的可以了,为什么后面声明的变量大小会影响前面的分页sql语句的执行呢?很奇怪[/quote] 你肯定是哪里弄错了,你五楼的语句我测下来是没问题。 我估计不是前面的语句执行有问题,而是你误以为报的错是前面语句执行的错误了
事理 2014-04-23
  • 打赏
  • 举报
回复
引用 20 楼 sdhp 的回复:
应该是你最后这里: declare @strsql nvarchar(1200) set @strsql='SELECT @i=COUNT(*) FROM '+@Table+@Where execute sp_executesql @strsql,N'@i int out',@Count OUT--返回总记录数 你定义的@strsql只有1200吧,改成nvarchar(max)看看
真的可以了,为什么后面声明的变量大小会影响前面的分页sql语句的执行呢?很奇怪
sdhp 2014-04-23
  • 打赏
  • 举报
回复
应该是你最后这里: declare @strsql nvarchar(1200) set @strsql='SELECT @i=COUNT(*) FROM '+@Table+@Where execute sp_executesql @strsql,N'@i int out',@Count OUT--返回总记录数 你定义的@strsql只有1200吧,改成nvarchar(max)看看
事理 2014-04-22
  • 打赏
  • 举报
回复
纠结,搞了一天还是搞不定。
guguda2008 2014-04-22
  • 打赏
  • 举报
回复
先建个临时表或表变量,把包含的字符串插进去,然后结果表关联临时表,条件用like即可。如果只要显示一条结果不显示匹配哪个字符,用exists。
guguda2008 2014-04-22
  • 打赏
  • 举报
回复
我说实话,楼主别怪我,你拼出来的这个查询本身就很秀逗,改个查询方式吧。
事理 2014-04-22
  • 打赏
  • 举报
回复
难道没有别的解了吗?
---涛声依旧--- 2014-04-22
  • 打赏
  • 举报
回复
如果可能,数据库升级到sql 2008就解决了
事理 2014-04-22
  • 打赏
  • 举报
回复
不知道大家的分页存储过程是如何解决sql语句过长的问题的,找了半天资料也没搞定,完整存储过程如下

create PROCEDURE [dbo].[proc_DataPagination]
(
	@Table nvarchar(1000),--表名,支持多表联查
	@Fields varchar(2000) = N'*',--字段名
	@Where nvarchar(4000) = N'',--where条件,不需要加where
	@OrderBy nvarchar(500) = N'',--排序条件,不需要加order by
	@CurrentPage int = 1, --当前页,从1开始,不是0
	@PageSize int = 10,--每页显示多少条数据
	@GetCount int =0,--获取的记录总数,0则获取记录总数,不为0则不获取
	@Count int = 0 output--总数
)
AS
BEGIN
	--没有提供排序字段,默认主键排序
	if @OrderBy is null or @OrderBy=''
	begin
		declare @tempTable varchar(200)
		--多表联查如果没有提供排序字段,自动找第一个表的主键进行排序
		if charindex(' on ',@Table)>0
			set @tempTable=substring(@Table,0,charindex(' ',@Table))
		else if charindex(',',@Table)>0
			begin
				set @tempTable=substring(@Table,0,charindex(',',@Table))
				--如果有别名如Article a,User u
				if(charindex(' ',@tempTable)>0)
					set @tempTable=substring(@tempTable,0,charindex(' ',@tempTable))
			end
		else
			set @tempTable=@Table--单表查询

		--查询表是否存在
		if not exists(select * from sysobjects where [name]=@tempTable)
		  begin
			raiserror('查询表%s不存在',12,12,@tempTable)
			return
		  end	

		--查询排序主键
		select @OrderBy=d.name from sysindexes a,sysobjects b,sysindexkeys c,syscolumns d 
		where c.id = object_id(@tempTable) and c.id = b.parent_obj   
			and a.name = b.name and b.xtype= 'PK ' and a.indid = 1 and d.colid = c.colid and d.id = c.id
		--如果没有主键,如视图
		if @OrderBy is null or @OrderBy = ''
		  begin
			raiserror('%s必须提供排序字段',12,12,@tempTable)
			return
		  end
	end

	--分页大小
	if @PageSize < 1
	   set @PageSize=10

	--默认当前页
	if @CurrentPage < 1
		set @CurrentPage = 1

	--选取字段
	if @Fields is null or @Fields = ''
		set @Fields='*'

	--过滤条件
	if @Where is null or @Where=''
		set @Where=''
	else
		set @Where=' WHERE '+@Where

	/*设置分页参数*/
	declare @startRow varchar(50),@endRow varchar(50)
	set @startRow = cast(((@CurrentPage - 1)*@PageSize + 1) as nvarchar(50))
	set @endRow = cast(@CurrentPage*@PageSize as nvarchar(50))
    
	declare @sql nvarchar(max)
    set @sql='SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY '+@OrderBy+') AS rownumber,'+@Fields+
		' FROM '+@Table+@Where+') AS tempdt WHERE rownumber BETWEEN '+@startRow+' AND '+@endRow
	print len(@sql)
	print @sql
	exec(@sql)

	/*
	如果@GetCount=0,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,
	把总页数传回给存储过程,避免再次计算总页数,当数据量很大时,select count(*)速度也要几秒钟)
	*/
	if(@GetCount=0)
	  begin
		declare @strsql nvarchar(1200)
		set @strsql='SELECT @i=COUNT(*) FROM '+@Table+@Where	
		execute sp_executesql @strsql,N'@i int out',@Count OUT--返回总记录数
	  end
	else
		set @Count=@GetCount
END

测试sql语句

declare @Count int
exec [proc_DataPagination] 'SL_User','UserId,UserName,RealName,IdentificationCard,Telphone,HomePhone,Email,LastLoginTime,UserStateId,LoginTotalCount','InTheRecycleBin=0 and (charindex('',''+''60''+'','','',''+ClassIds+'','')>0 or charindex('',''+''61''+'','','',''+ClassIds+'','')>0 or charindex('',''+''62''+'','','',''+ClassIds+'','')>0 or charindex('',''+''63''+'','','',''+ClassIds+'','')>0 or charindex('',''+''64''+'','','',''+ClassIds+'','')>0 or charindex('',''+''65''+'','','',''+ClassIds+'','')>0 or charindex('',''+''66''+'','','',''+ClassIds+'','')>0 or charindex('',''+''77''+'','','',''+ClassIds+'','')>0 or charindex('',''+''78''+'','','',''+ClassIds+'','')>0 or charindex('',''+''79''+'','','',''+ClassIds+'','')>0 or charindex('',''+''80''+'','','',''+ClassIds+'','')>0 or charindex('',''+''81''+'','','',''+ClassIds+'','')>0 or charindex('',''+''82''+'','','',''+ClassIds+'','')>0 or charindex('',''+''83''+'','','',''+ClassIds+'','')>0 or charindex('',''+''84''+'','','',''+ClassIds+'','')>0 or charindex('',''+''85''+'','','',''+ClassIds+'','')>0 or charindex('',''+''86''+'','','',''+ClassIds+'','')>0 or charindex('',''+''87''+'','','',''+ClassIds+'','')>0 or charindex('',''+''88''+'','','',''+ClassIds+'','')>0 or charindex('',''+''89''+'','','',''+ClassIds+'','')>0 or charindex('',''+''90''+'','','',''+ClassIds+'','')>0 or charindex('',''+''91''+'','','',''+ClassIds+'','')>0 or charindex('',''+''92''+'','','',''+ClassIds+'','')>0 or charindex('',''+''93''+'','','',''+ClassIds+'','')>0) and userid=201 and userid=482 and userid=483 and userid=488 and userid=530 and userid=531 and userid=532','',1,20,0,@Count output
select @Count
事理 2014-04-22
  • 打赏
  • 举报
回复
exec(@sql)也不行,会出现sql语句截断 消息 156,级别 15,状态 1,第 1 行 关键字 'use' 附近有语法错误。 实际上sql语句没有问题
  • 打赏
  • 举报
回复
exec (@sql)即可
事理 2014-04-22
  • 打赏
  • 举报
回复
打印出来的长度也只有 1476 打印出来的sql测试语句如下 SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY UserName) AS rownumber,UserId,UserName,RealName,IdentificationCard,Telphone,HomePhone,Email,LastLoginTime,UserStateId,LoginTotalCount FROM SL_User WHERE InTheRecycleBin=0 and (charindex(','+'60'+',',','+ClassIds+',')>0 or charindex(','+'61'+',',','+ClassIds+',')>0 or charindex(','+'62'+',',','+ClassIds+',')>0 or charindex(','+'63'+',',','+ClassIds+',')>0 or charindex(','+'64'+',',','+ClassIds+',')>0 or charindex(','+'65'+',',','+ClassIds+',')>0 or charindex(','+'66'+',',','+ClassIds+',')>0 or charindex(','+'77'+',',','+ClassIds+',')>0 or charindex(','+'78'+',',','+ClassIds+',')>0 or charindex(','+'79'+',',','+ClassIds+',')>0 or charindex(','+'80'+',',','+ClassIds+',')>0 or charindex(','+'81'+',',','+ClassIds+',')>0 or charindex(','+'82'+',',','+ClassIds+',')>0 or charindex(','+'83'+',',','+ClassIds+',')>0 or charindex(','+'84'+',',','+ClassIds+',')>0 or charindex(','+'85'+',',','+ClassIds+',')>0 or charindex(','+'86'+',',','+ClassIds+',')>0 or charindex(','+'87'+',',','+ClassIds+',')>0 or charindex(','+'88'+',',','+ClassIds+',')>0 or charindex(','+'89'+',',','+ClassIds+',')>0 or charindex(','+'90'+',',','+ClassIds+',')>0 or charindex(','+'91'+',',','+ClassIds+',')>0 or charindex(','+'92'+',',','+ClassIds+',')>0 or charindex(','+'93'+',',','+ClassIds+',')>0) and userid=201 and userid=482 and userid=483 and userid=488 and userid=530 and userid=531 and userid=532) AS tempdt WHERE rownumber BETWEEN 1 AND 20
事理 2014-04-22
  • 打赏
  • 举报
回复
print 打印出来的sql语句可以正常执行,数据库是sql2005,改写为如下用exec还是无法执行

declare @sql nvarchar(max)
    set @sql='SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY '+@OrderBy+') AS rownumber,'+@Fields+
		' FROM '+@Table+@Where+') AS tempdt WHERE rownumber BETWEEN '+@startRow+' AND '+@endRow
	print len(@sql)
	print @sql
	exec sp_executesql @sql

加载更多回复(4)

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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