图片 1

SQLServer数据库表字段超长,找到超长字段脚本

1.sql存储过程中使用 output

平时开发系统时偶尔会遇到数据超长导致往数据库中保存时出错。

CREATE PROCEDURE [dbo].[P_Max]
@a int, -- 输入
@b int, -- 输入
@Returnc int output --输出
AS 

if (@a>@b) 
   set @Returnc =@a
else
   set @Returnc =@b

-- 调用
declare @Returnc int 
exec P_Max  2,3,@Returnc output 
select @Returnc

使用下边的脚本可以方便的找出超长的字段。

 2.Sql Server
增加字段、修改字段、修改类型、修改默认值

1.通过正式表创建临时表,修改临时表中varchar、nvarchar的长度为max

 

declare @temp_table_name varchar(50);
declare @table_name varchar(50);
declare @sql varchar(max);
set @table_name='TableName';--正式表表名:此处需要修改
set @temp_table_name = @table_name+'_temp';--临时表表名:此处需要修改

--根据正式表创建临时表
set @sql = 'select * into '+@temp_table_name+' from '+@table_name +' where 1<>1;';
exec(@sql);

--修改varchar/nvarchar临时表字段长度为max
set @sql = '';
select @sql=@sql+('alter table '+@temp_table_name+' alter column '+b.name+' '+c.name+'(max);')  
from sysobjects a,syscolumns b,systypes c 
where a.id=b.id and a.name=@temp_table_name 
and a.xtype='U'and b.xusertype=c.xusertype
and c.name in ('varchar','nvarchar')
order by b.colid;

exec(@sql);

--手动往临时表中写入数据
 ①修改字段名:

  alter table 表名 rename column A to B

 ②修改字段类型:

  alter table 表名 alter column 字段名 type not null

 ③修改字段默认值
  alter table 表名 add default (0) for 字段名 with values

  如果字段有默认值,则需要先删除字段的约束,在添加新的默认值,

  select c.name from sysconstraints a 
  inner join syscolumns b on a.colid=b.colid 
  inner join sysobjects c on a.constid=c.id
  where a.id=object_id('表名') 
  and b.name='字段名'

  根据约束名称删除约束

  alter table 表名 drop constraint 约束名

  根据表名向字段中增加新的默认值

  alter table 表名 add default (0) for 字段名 with values

④增加字段:

  alter table 表名 add 字段名 type not null default 0

⑤删除字段:

  alter table 表名 drop column 字段名;

2.数据手动写入临时表后,查找超长字段

 

declare @temp_table_name varchar(50);
declare @table_name varchar(50);
declare @sql varchar(max);
set @table_name='TableName';--正式表表名:此处需要修改
set @temp_table_name = @table_name+'_temp';--临时表表名:此处需要修改
--校验临时表是哪个字段超长
create table #col_tab
(
    id int,
    col_name varchar(100),
    col_condition varchar(500)
);

insert into #col_tab(id,col_name,col_condition)
select ROW_NUMBER() over(order by b.colid) id,
b.name,
(case c.name when 'nvarchar' then 'len' when 'varchar' then 'datalength' end)+
'('+b.name+')>'+cast((case c.name when 'nvarchar' then b.length/2 when 'varchar' then b.length end) as varchar) 
from sysobjects a,syscolumns b,systypes c 
where a.id=b.id and a.name=@table_name 
and a.xtype='U'and b.xusertype=c.xusertype
and c.name in ('varchar','nvarchar')
order by b.colid;

select * from #col_tab ;

declare @cnt int ;
select @cnt = COUNT(*) from #col_tab;

declare @index int;
declare @col_condition varchar(500);
declare @col_name varchar(100);

set @index=1;
while @index<=@cnt
begin
    select @col_condition = col_condition,@col_name=col_name from #col_tab where id = @index;
    set @sql = 'declare @condition_cnt int;';
    set @sql = @sql+'select @condition_cnt=COUNT(*) from '+@temp_table_name+' where '+@col_condition+';';
    --set @sql = @sql+'print @condition_cnt;';
    set @sql = @sql+'if(@condition_cnt>0)
    begin
        print ''['+@col_name+']字段超长!'';
    end;';
exec(@sql);
    set @index=@index+1;
end;

drop table #col_tab;

 2.nvarchar(max)一坑

 3.新建测试表

 

CREATE TABLE [dbo].[USERS](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [name] [varchar](30) NULL,
    [password] [varchar](30) NULL,
    [roleid] [int] NULL,
PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

  监控邮件中有个变量使用了nvarchar(max),有一天数据多了,总字节有150048,但是总是读出来9000多个。郁闷,查了查,才知道是啥问题。

表截图如下:

       

图片 1

  关于 varchar max的误区

修改表名,运行
1.通过正式表创建临时表,修改临时表中varchar、nvarchar的长度为max 脚本