隐藏

向存储过程传递大文本数据

发布:2015/1/17 13:24:59作者:管理员 来源:本站 浏览次数:1264

向sql server的存储过程传输一个上万字的大文本不是一个好的设计,但是有时候我们确实可能会用到,本文只是介绍我们应该怎么做,而并不建议使用这种方法

1.首先了解一下可以传输/保存大文本的数据类型

    varchar 最大8000非unicode字符,一个汉字会被分为2个存储长度,即最大可以存储4000汉字,注意:数字和字母占用1个长度

    nvarchar 最大4000个unicode字符,一个汉字会被分为1个存储长度,即最大可以存储4000汉字,注意:数字和字母也会被作为一个汉字来储存,占用2个长度

    text 非unicode 2G

    ntext  unicode 2G

2.做一个测试

drop table t_test_varchar
go
create table t_test_varchar(
col1 varchar(8000),
col2 varchar(100)
)
go

在这儿我们会收到一个警告信息:警告: 已创建表 't_test_varchar',但其最大行大小(8125)超过了每行的最大字节数(8060)。如果结果行长度超过 8060 字节,则此表中行的 INSERT 或 UPDATE 将失败。后面的测试,这个恶魔会经常出现。而且这个地方有个奇怪的事情发生,就是我们的长度明明是8100,而错误报告确说是8125,可能多出来的25 是用来存放用户id或者索引等信息的隐含列的内容,我们在这里就不深究了。

insert into t_test_text values(space(8000),space(60))
会报告:无法创建大小为 8073 的行,该值大于允许的最大值 8060。

但是我们的确是希望表中能存放大于8060的数据,怎么办?

3.用text列来保存大于8060长度的数据
drop table t_test_text
go
create table t_test_text(
col1 text,
col2 text,
col3 text,
col4 text
)
go

4.测试保存数据
insert into t_test_text values('a'+space(8000)+'b','c'+space(8000)+'d','e'+space(8000)+'f','g'+space(8000)+'h')
go

通常能够执行成功,但是这里有一点需要注意。就是text到底能存储多少内容的问题,text类型本身能最大存储量是2G,但是在向text文本或者变量中填入值得时候会受到一个系统参数@@textsize的限制。可以使用以下方法检查和设置这个参数
--text 传输大小(内存容量)由参数@@textsize决定
--select @@textsize
--set @@textsize 2147483647 --2G


5.向存储过程传递大文本数据(存储过程最多可以有2100个参数)
例子如下:

--测试数据长度的存储过程
drop procedure p_test_text
go

create procedure p_test_text
 (@iv_data text)
as

 declare @lv_data1 varchar(8000);
 declare @lv_data2 varchar(8000);
 declare @lv_data3 varchar(8000);
 declare @lv_data4 varchar(8000);
 set @lv_data1 = substring(@iv_data,1,8000);
 set @lv_data2 = substring(@iv_data,8001,8000);
 set @lv_data3 = substring(@iv_data,16001,8000);
 set @lv_data4 = substring(@iv_data,24001,8000);

insert into t_test_text values(@lv_data1,@lv_data2,@lv_data3,@lv_data4);

select
substring(col1,1,20) + substring(col1,7990,20),
substring(col2,1,20) + substring(col2,7990,20),
substring(col3,1,20) + substring(col3,7990,20),
substring(col4,1,20) + substring(col4,7990,20) from t_test_text

go

--最好是先设置一下@@textsize
set textsize 1024000

--测试,注意下面红色区域是8000 * 4个字符

exec p_test_text



如果大家在程序中调用时发现“set textsize”不起作用,请这样做(每种语言的动态sql语句调用都不一样,请大家根据自己的语言灵活运用)

string ls_sql = "set textsize 1024000;exec p_test_text ?" --注意set textsize

string ls_bigText=space(100000)

EXECUTE IMMEDIATE :ls_sql USING :ls_bigText;