create table test 
(id int,
 name varchar(10),
 con text not null);
应用脚本:
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
COMMIT
BEGIN TRANSACTION
CREATE TABLE Tmp_test
(
  id int NULL,
name varchar(10) NULL,
con text NULL

GO
IF EXISTS(SELECT * FROM test)
 EXEC('INSERT INTO Tmp_test(id, name, con)
SELECT id, name, con FROM test TABLOCKX')
GO
DROP TABLE test
GO
EXECUTE sp_rename 'Tmp_test', 'test'
GO
COMMIT

解决方案 »

  1.   

    在他建数据库中的一个表之后,用户可以改变中原先定义的许多选项,可以增加列、删除列、改变表名和改变表的所有者。但是不能直接改变某一个列的数据类型、null值或者identity属性。这些项可以能过间接的方法来改变。例如:可以在表中增加一个新列,该更具有新的数据类型、null值或者identity属性,然后把数据从旧列输到新列,最后把旧列删除。
    主要用到以下的命令:
    (1)改变数据库的select into属性
    exec sp_dboption
    @dbname='XXXXX(数据库名)',
    @optname='select into/bulkcopy',
    @optvalue=true
    (2)新增一列
    alter table XXX(表名)add column XXX(列名) varchar(50) null
    (3)输入数据到新列
    select column_列 into column_新 form XXX(表名)
    (4)删除一列
    alter table XXX(表名)drop column XXX(列名)
      

  2.   

    谢谢guo和dahaidao的回答。
    我的原意是这样的,我有好几个库,里面几乎所有表的字段设计得不大好,把大多的字段都设为不为空了,此时客户已经用这系统好久了,现在需要把除主键之外的所有字段改为可空,因此我想写个存储过程来执行,而不想一个一个地修改,但是这text字段无法改动。
    guo的做法我也想过,但还要把那么多的库和表都生成脚本,我完全可以去用手工改动了:(
    dahaidao说的对普通的字段是没问题的,但对我所问的text字段用alter table .. alter column ..是无法改动的,这是想问有什么办法可以通过sql语句进行改动,以变我可以用存储过程来解决。
      

  3.   

    给你一个比较好的办法,不过也是折中,就是给非空字段指定默认值
    接上表
    ALTER TABLE test ADD CONSTRAINT DF_test_con DEFAULT ('') FOR con
    这样插入语句就可以:
    insert into test(id,name) values(1,'abc')
    而不用对text字段指定值,表中使用其默认值.
      

  4.   

    方法是有的你可以
    第一部就要找到所有列但是他们不是主建!
    select b.name,b.isnullable,b.type from syscolumns b
    where b.xtype='U' and 
          b.name not in (select name from sysobjects a where a.id=b.id and xtype='PK')
    然后你就可以定义一个cursor
    declare @name varchar(100),@isnullable  int,@type varchar(10),@sql varchar(200),@tablename varchar(100),@id int
    declare kkk cursor for 
    select b.name,b.isnullable,b.type,b.id from syscolumns b
    where b.xtype='U' and 
          b.name not in (select name from sysobjects a where a.id=b.id and xtype='PK')
    最后对其访问!
    open kkk
    fetch next from kkk into @name,@isnullable,@type,@id
    while @@FETCH_STATUS=0  
    begin
         select @tablename=object_name(@id)
         if @type<>'text' then
            '求表明
            begin
            select @sql='alter table '+@tablename+' alter column '+@name+' null'
            exec(@sql)
            end
         else
            select @name, @tablename
         fetch next from kkk into @name,@isnullable,@type
    end
    我的方法是对不是主建的列且数据类型不是text进行更改!
    对是text的类打印出来!
      

  5.   

    将所有text类型的字段改为允许空。
    update syscolumns set  isnullable = 1 where id  in ( select id from sysobjects where xtype ='U' and name <> 'dtproperties'  ) and xtype= 35
     不过我这里没有考虑主键的问题。
    to wwl007(疑难杂症):
    有一次我通过 syscolumns 将所有varchar类型的字段,全部改为nvarchar类型。但是改完后中文都变成了乱码,不知道是什么原因???。有没有解决的方法?
      

  6.   

    to pxq,你的语句运行过了吗? 一个计算字段怎么能直接改变它的值?
      

  7.   

    wwl007(疑难杂症) ,
    你还有时间上网呀?
      

  8.   

    to wwl007(疑难杂症),你的语句虽然没经过运行,但也清楚地指明了一种解决办法,但是用alter时alter column @name <type> null时,这个<type>如何方便地得到呢?我想了一会儿,觉得难点在不同的类型,有的有长度,有的还有精度,不知可有简捷的办法可以得到字段类型呢?
      

  9.   

    :guo(正在学Oracle和Solaris) 说的对!就是那样度!syscolumne有你的所有的信息!平且!
    如果你修改的时候好像不需要具体的类型和精度!
      

  10.   

    to guo(正在学Oracle和Solaris) :
    刚才那个是不行,isnullable 是系统的列不能修改。改成下面的语句就可以了。update syscolumns set  typestat = 0 where id  in ( select id from sysobjects where xtype ='U' and name <> 'dtproperties'  ) and xtype= 35