如题,整个函数命令如下,主要目的是根据用户输入的列名拼凑动态SQL语句:
--/**
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--**/
-- =============================================
-- Author: <Author:Eagle>
-- Create date: <2012-07-30>
-- Description: <for dynamic sql statement of dynamic columns select of table payresult by birt design>
-- =============================================
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE NAME = 'test_function')
DROP FUNCTION test_function
GO
CREATE FUNCTION test_function(@list varchar(max), @EEID varchar(max), @paytime varchar(max))
RETURNS varchar(max)
--RETURNS TEXT (2147483647)
AS
BEGIN
DECLARE @ResultVar varchar(v)
--DECLARE @ResultVar TEXT (2147483647)
DECLARE @mytemp table(
ss varchar(v) not null ,myid int not null)
DECLARE @str varchar(max)
DECLARE @str1 varchar(max)
DECLARE @payend varchar(max)
DECLARE @curr int
DECLARE @prev int
--/**
SET @str=@list
SET @str1=@EEID
SET @payend=@paytime
--**/
/**调试数据
SET @str='1,2,501,123,56,888,999,666,324,100,601,2,501,123,56,888,999,666,324,100,601,2,50,308'
SET @str1='0,1001'
SET @payend='2012-06-30 00:00:00.000'
**/
SET @curr=1
SET @prev=1
WHILE @prev < LEN(@str)
BEGIN
SET @curr=CHARINDEX(',',@str,@prev)
IF @curr>@prev
INSERT @mytemp SELECT SUBSTRING(@str,@prev,@curr-@prev), 0
ELSE
BEGIN
INSERT @mytemp SELECT SUBSTRING(@str,@prev,LEN(@str)-@prev+1) ,0
BREAK
END
SET @prev=@curr+1
END
UPDATE @mytemp SET myid =(CASE WHEN SS%50 = 0 THEN CEILING(ss/50) ELSE CEILING(SS/50)+1 END)
UPDATE @mytemp SET SS=(CASE WHEN SS%50 = 0 THEN 50 ELSE SS%50 END)
--拼凑SQL语句
DECLARE @n int
DECLARE @ss varchar(max)
DECLARE @sql1 varchar(max)
DECLARE @sql2 varchar(max)
DECLARE @sql3 varchar(max)
DECLARE @x varchar(max)
DECLARE @x1 varchar(max)
DECLARE @y varchar(max)
DECLARE @y1 varchar(max)
DECLARE @y2 varchar(max)
SET @y=''
SET @y1=''
SET @n = 1
SET @sql2=''
WHILE (@n<=(SELECT MAX(myid) FROM @mytemp))
BEGIN
SET @y2=''
DECLARE test CURSOR FOR
SELECT ss FROM (SELECT DISTINCT * FROM @mytemp)Z WHERE myid = @n ORDER BY ss
OPEN test
FETCH NEXT FROM test INTO @ss
WHILE @@FETCH_STATUS=0
BEGIN
--SET @x=@ss
--SET @x='HRPayResult_'+CONVERT(varchar(200),@n)+'.hrFigure'+@x+','
SET @x1=@ss
SET @x1='hrFigure'+@x1+','
SET @y2=@y2+@x1
SET @y1=@y1+'ISNULL ('+'PayResult_'+CONVERT(varchar(200),@n)+'.list'+@ss+',0)'+' AS NEWCOLUMNS_'+@ss+'_'+CONVERT(varchar(200),@n)+','
FETCH NEXT FROM test INTO @ss
END
SET @x=SUBSTRING(@y1,1,LEN(@y1)-1)
CLOSE test
DEALLOCATE test
IF(@n in (SELECT DISTINCT(myid) FROM @mytemp))
BEGIN
SET @sql1='(select EEID, '+SUBSTRING(@y2,1,LEN(@y2)-1)+' from PayResult '+'where EEID IN '+'('+@str1+')'+' AND PayEnd ='+''''+@payend+''''+' AND Action <= '+'''E'''+' AND PgIndex = '+convert(varchar(200),@n)+')PayResult_'+convert(varchar(200),@n)
SET @sql2=@sql2+'LEFT JOIN '+@sql1+' ON HRPayResult_'+convert(varchar(200),@n)+'.hrEEID '+' = HRPayResult_0'+'.hrEEID '+' '
END
SET @n=@n+1
END
SET @sql3='SELECT DISTINCT * FROM ('+'select PayResult_0.EEID, A.EEName, PayResult_0.PayEnd, PayResult_0.BatchID, PayResult_0.Action, PayResult_0.AuditNo, PayResult_0.FinalApp, PayResult_0.PeriodID, '+@x+' from (SELECT * FROM PAYRESULT WHERE EEID IN '+'('+@str1+')'+' AND PayEnd ='+''''+@payend+''''+' AND ACTION <= '+'''E'''+')PayResult_0 '+@sql2+'LEFT JOIN EEInfo A ON PayResult_0.EEID = A.EEID'+')A'
SET @ResultVar = @sql3
--print @ResultVar
RETURN @ResultVar
END如上,可以顺利打印全部语句,将其考下可以正确执行,但是对生成的函数进行执行就无法得出全部语句,打印是只能出2000个字符。EXEC(),EXEC SP_EXECUTESQL都无法执行(字符串被截断)。
问题就是:原因何在?BY THE WAY,sp_executesql执行的时候我是做了调整了,Nvarchar(max)当然是改了的。为什么得不到完整的语句呢?请高手指教!谢谢!
第一次发帖,不知道如何散分,或者我就没有分,请各位高手海涵!
--/**
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--**/
-- =============================================
-- Author: <Author:Eagle>
-- Create date: <2012-07-30>
-- Description: <for dynamic sql statement of dynamic columns select of table payresult by birt design>
-- =============================================
IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE NAME = 'test_function')
DROP FUNCTION test_function
GO
CREATE FUNCTION test_function(@list varchar(max), @EEID varchar(max), @paytime varchar(max))
RETURNS varchar(max)
--RETURNS TEXT (2147483647)
AS
BEGIN
DECLARE @ResultVar varchar(v)
--DECLARE @ResultVar TEXT (2147483647)
DECLARE @mytemp table(
ss varchar(v) not null ,myid int not null)
DECLARE @str varchar(max)
DECLARE @str1 varchar(max)
DECLARE @payend varchar(max)
DECLARE @curr int
DECLARE @prev int
--/**
SET @str=@list
SET @str1=@EEID
SET @payend=@paytime
--**/
/**调试数据
SET @str='1,2,501,123,56,888,999,666,324,100,601,2,501,123,56,888,999,666,324,100,601,2,50,308'
SET @str1='0,1001'
SET @payend='2012-06-30 00:00:00.000'
**/
SET @curr=1
SET @prev=1
WHILE @prev < LEN(@str)
BEGIN
SET @curr=CHARINDEX(',',@str,@prev)
IF @curr>@prev
INSERT @mytemp SELECT SUBSTRING(@str,@prev,@curr-@prev), 0
ELSE
BEGIN
INSERT @mytemp SELECT SUBSTRING(@str,@prev,LEN(@str)-@prev+1) ,0
BREAK
END
SET @prev=@curr+1
END
UPDATE @mytemp SET myid =(CASE WHEN SS%50 = 0 THEN CEILING(ss/50) ELSE CEILING(SS/50)+1 END)
UPDATE @mytemp SET SS=(CASE WHEN SS%50 = 0 THEN 50 ELSE SS%50 END)
--拼凑SQL语句
DECLARE @n int
DECLARE @ss varchar(max)
DECLARE @sql1 varchar(max)
DECLARE @sql2 varchar(max)
DECLARE @sql3 varchar(max)
DECLARE @x varchar(max)
DECLARE @x1 varchar(max)
DECLARE @y varchar(max)
DECLARE @y1 varchar(max)
DECLARE @y2 varchar(max)
SET @y=''
SET @y1=''
SET @n = 1
SET @sql2=''
WHILE (@n<=(SELECT MAX(myid) FROM @mytemp))
BEGIN
SET @y2=''
DECLARE test CURSOR FOR
SELECT ss FROM (SELECT DISTINCT * FROM @mytemp)Z WHERE myid = @n ORDER BY ss
OPEN test
FETCH NEXT FROM test INTO @ss
WHILE @@FETCH_STATUS=0
BEGIN
--SET @x=@ss
--SET @x='HRPayResult_'+CONVERT(varchar(200),@n)+'.hrFigure'+@x+','
SET @x1=@ss
SET @x1='hrFigure'+@x1+','
SET @y2=@y2+@x1
SET @y1=@y1+'ISNULL ('+'PayResult_'+CONVERT(varchar(200),@n)+'.list'+@ss+',0)'+' AS NEWCOLUMNS_'+@ss+'_'+CONVERT(varchar(200),@n)+','
FETCH NEXT FROM test INTO @ss
END
SET @x=SUBSTRING(@y1,1,LEN(@y1)-1)
CLOSE test
DEALLOCATE test
IF(@n in (SELECT DISTINCT(myid) FROM @mytemp))
BEGIN
SET @sql1='(select EEID, '+SUBSTRING(@y2,1,LEN(@y2)-1)+' from PayResult '+'where EEID IN '+'('+@str1+')'+' AND PayEnd ='+''''+@payend+''''+' AND Action <= '+'''E'''+' AND PgIndex = '+convert(varchar(200),@n)+')PayResult_'+convert(varchar(200),@n)
SET @sql2=@sql2+'LEFT JOIN '+@sql1+' ON HRPayResult_'+convert(varchar(200),@n)+'.hrEEID '+' = HRPayResult_0'+'.hrEEID '+' '
END
SET @n=@n+1
END
SET @sql3='SELECT DISTINCT * FROM ('+'select PayResult_0.EEID, A.EEName, PayResult_0.PayEnd, PayResult_0.BatchID, PayResult_0.Action, PayResult_0.AuditNo, PayResult_0.FinalApp, PayResult_0.PeriodID, '+@x+' from (SELECT * FROM PAYRESULT WHERE EEID IN '+'('+@str1+')'+' AND PayEnd ='+''''+@payend+''''+' AND ACTION <= '+'''E'''+')PayResult_0 '+@sql2+'LEFT JOIN EEInfo A ON PayResult_0.EEID = A.EEID'+')A'
SET @ResultVar = @sql3
--print @ResultVar
RETURN @ResultVar
END如上,可以顺利打印全部语句,将其考下可以正确执行,但是对生成的函数进行执行就无法得出全部语句,打印是只能出2000个字符。EXEC(),EXEC SP_EXECUTESQL都无法执行(字符串被截断)。
问题就是:原因何在?BY THE WAY,sp_executesql执行的时候我是做了调整了,Nvarchar(max)当然是改了的。为什么得不到完整的语句呢?请高手指教!谢谢!
第一次发帖,不知道如何散分,或者我就没有分,请各位高手海涵!
解决方案 »
- 求条SQL语句,谢谢
- 如何組織成一條記錄
- 请求各位大侠:"llVal":is not a member of 'tagVARIANT'(为什么我的_variant_t 没有64类型,该如何解决这个问题) 开发环境 VC6+ADO
- 请问这个SQL怎么写?
- 困绕我很久的查询类型,进来帮帮吧,应该是很简单的
- 装了SQL补丁后进不了系统
- 我的mssql服务已经启动,但没有监听1433端口,为什么?
- 内网SQL SERVER连接问题
- SQL Server备份后的数据怎么恢复,在线等待并结贴
- BCP导成文本时把空格去掉???
- sqlservr.exe上传占网速
- GPS经纬度转百度经纬度,在SQL语句里怎么做。
改成存储吧。
RETURN @ResultVar
只是返回一个字符串?贴出打印出来的字符串是什么呢?sp_executesql(test_fun(...));不行?报什么错?
DECLARE @Z VARCHAR(MAX)
SET @Z = dbo.test_function('1,2,501,123,56,888,999,666,324,100,601,2,501,123,56,888,999,666,324,100,601,2,50,308','0,1001','2012-06-30 00:00:00.000')
print @z--得到的字符串不全
print len(@z)--长度只有2000,在函数中调试可以知道有3000+
select @z--结果一样
exec (@z)--所以无法执行
或者嫂子有别的办法咩?请指教!谢谢!
是可以正确执行的,但是输出就会被截断,无法正确EXEC 或者exec sp_executesql。未知如何应对。谢谢兄台,请指教。盼望解答。
'test_function' 附近有语法错误。谢谢解答,请多关照,盼望解答!
DROP FUNCTION f_test
GO
CREATE FUNCTION f_test()
RETURNS varchar(max)
AS
BEGIN
DECLARE @s varchar(max)
SET @s=REPLICATE('a',30000)
RETURN @s
END
DECLARE @a varchar(max)
SET @a=dbo.f_test()
SELECT @a,LEN(@a)
上面这个测试最大值是8000,你在你sql上试试
你的sql 版本是什么改成 varchar(8000)试试
sp_executesql( dbo.test_fun(...) );
呢?
declare @a varchar(8000)
select @a = dbo.test_function('1,2,501,123,56,888,999,666,324,100,601,2,501,123,56,888,999,666,324,100,601,2,50,308','0,1001','2012-06-30 00:00:00.000')
print @a
print len(@a)
结果
SELECT DISTINCT * FROM (select PayResult_0.EEID, A.EEName, PayResult_0.PayEnd, PayResult_0.BatchID, PayResult_0.Action, PayResult_0.AuditNo, PayResult_0.FinalApp, PayResult_0.PeriodID, ISNULL (PayResult_1.list1,0) AS NEWCOLUMNS_1_1,ISNULL (PayResult_1.list2,0) AS NEWCOLUMNS_2_1,ISNULL (PayResult_1.list50,0) AS NEWCOLUMNS_50_1,ISNULL (PayResult_2.list50,0) AS NEWCOLUMNS_50_2,ISNULL (PayResult_2.list6,0) AS NEWCOLUMNS_6_2,ISNULL (PayResult_3.list23,0) AS NEWCOLUMNS_23_3,ISNULL (PayResult_7.list24,0) AS NEWCOLUMNS_24_7,ISNULL (PayResult_7.list8,0) AS NEWCOLUMNS_8_7,ISNULL (PayResult_11.list1,0) AS NEWCOLUMNS_1_11,ISNULL (PayResult_13.list1,0) AS NEWCOLUMNS_1_13,ISNULL (PayResult_14.list16,0) AS NEWCOLUMNS_16_14,ISNULL (PayResult_18.list38,0) AS NEWCOLUMNS_38_18,ISNULL (PayResult_20.list49,0) AS NEWCOLUMNS_49_20 from (SELECT * FROM PAYRESULT WHERE EEID IN (0,1001) AND PayEnd ='2012-06-30 00:00:00.000' AND ACTION <= 'E')PayResult_0 LEFT JOIN (select EEID, hrFigure1,hrFigure2,hrFigure50 from PayResult where EEID IN (0,1001) AND PayEnd ='2012-06-30 00:00:00.000' AND Action <= 'E' AND PgIndex = 1)PayResult_1 ON HRPayResult_1.hrEEID = HRPayResult_0.hrEEID LEFT JOIN (select EEID, hrFigure50,hrFigure6 from PayResult where EEID IN (0,1001) AND PayEnd ='2012-06-30 00:00:00.000' AND Action <= 'E' AND PgIndex = 2)PayResult_2 ON HRPayResult_2.hrEEID = HRPayResult_0.hrEEID LEFT JOIN (select EEID, hrFigure23 from PayResult where EEID IN (0,1001) AND PayEnd ='2012-06-30 00:00:00.000' AND Action <= 'E' AND PgIndex = 3)PayResult_3 ON HRPayResult_3.hrEEID = HRPayResult_0.hrEEID LEFT JOIN (select EEID, hrFigure24,hrFigure8 from PayResult where EEID IN (0,1001) AND PayEnd ='2012-06-30 00:00:00.000' AND Action <= 'E' AND PgIndex = 7)PayResult_7 ON HRPayResult_7.hrEEID = HRPayResult_0.hrEEID LEFT JOIN (select EEID, hrFigure1 from PayResult where EEID IN (0,1001) AND PayEnd ='2012-06-30 00:00:00.000' AND Action <= 'E' AND PgIndex = 11)PayResult_11 ON HRPayResult_11.hrEEID = HRPayResult_0.hrEEID LEFT JOIN (select EEID, hrFigure1 from PayResult where EEID IN (0,1001) AND PayEnd ='2012-06-30 00:00:00.000' AND Action <= 'E' AND PgIndex = 13)PayResult_13 ON HRPayResult_13.hrEEID = HRPayResult_0.hrEEID LEFT JOIN (select EEID, hrFigure16 from PayResult where EEID IN (0,1001) AND PayEnd ='2012-06-30 00:00:00.000' AND Action <= 'E' AND PgIndex = 14)PayResult_14 ON HRPayResult_14.hrEEID = HRPayResult_0.hrEEID LEFT JOIN (select EEID, hrFigure38 from PayResult where EEID IN (0,1001) AND PayEnd ='2012-06-30 00:00:00.000' AND Action <= 'E' AND PgIndex = 18)PayResult_18 ON HRPayResult_18.hrEEID = HRPayResult_0.hrEEID LEFT JOIN (select EEID, hrFigure49 from PayResult where EEID IN (0,1001) AND PayEnd ='2012-06-30 00:00:00.000' AND Action <= 'E' AND PgIndex = 20)PayResult_20 ON HRPayResult_20.hrEEID = HRPayResult_0.hrEEID LEFT JOIN EEInfo A ON PayResult_0.EEID = A.EEID)A
2897
没有问题啊