CREATE
PROC
SP_CHANGE_TABLE_CHARTYPE
(
@tableName nvarchar ( 128 ) -- 表名
)
AS
DECLARE @varcharTypeId tinyint -- varchar數據類型編號
DECLARE @textTypeId tinyint -- text數據類型編號
DECLARE @ColumnName nvarchar ( 128 ) -- 系統列名
DECLARE @CType VARCHAR ( 1 ) -- 類型
DECLARE @IsNullAble char ( 1 ) -- 是否允許為空
DECLARE @Length int -- 欄位長度
DECLARE @ColumnType int -- 列類型
DECLARE @DCName nvarchar ( 128 ) -- 默認值約束名稱
DECLARE @DCValue nvarchar ( max ) -- 默認值約束表達式
DECLARE @CCName nvarchar ( 128 ) -- 自定義約束名稱
DECLARE @CCValue nvarchar ( max ) -- 自定義約束表達式
DECLARE @objectid int
DECLARE @sqlstr nvarchar ( max )
IF NOT EXISTS ( SELECT * FROM sys.tables WHERE name = @tableName )
BEGIN
RAISERROR ( ' 數據表不存在,請確認表名是否正確! ' , 16 , 1 )
RETURN
END
SET @objectid = OBJECT_ID ( @tableName )
-- 取得varchar, text類別編碼,名稱不能重複,可通過名稱查詢【已測試過】
SELECT @varcharTypeId = system_type_id FROM sys.types WHERE name = ' varchar '
SELECT @textTypeId = system_type_id FROM sys.types WHERE name = ' text '
-- 取得主鍵列名
SELECT COL_NAME (IC. object_id , IC.column_id) AS ColumnName
INTO #PrimaryColumn
FROM sys.index_columns AS IC
LEFT JOIN sys.indexes AS I ON I. object_id = IC. object_id AND I.index_id = IC.index_id
WHERE I.is_primary_key = 1
AND IC. object_id = @objectid
-- 更新類型
DECLARE cur_columns_varchar CURSOR STATIC FOR
-- 查找非主鍵varchar, text類型字段並找出相應默認值及約束
SELECT C.name AS ColumnName, C.is_nullable, D.name AS DCName, D.definition AS DCValue,
CK.name AS CCName, CK.definition AS CCValue, C.max_length, C.system_type_id
FROM sys.columns AS C -- 系統字段視圖
LEFT JOIN sys.default_constraints AS D ON D.parent_object_id = C. object_id AND D.parent_column_id = C.column_id -- 默認值視圖
LEFT JOIN sys.check_constraints AS CK ON CK.parent_object_id = C. object_id AND CK.parent_column_id = C.column_id -- 約束視圖
WHERE C. object_id = @objectid
AND (C.system_type_id = @varcharTypeId OR C.system_type_id = @textTypeId )
AND NOT EXISTS ( SELECT * FROM #PrimaryColumn WHERE ColumnName = C.name)
OPEN cur_columns_varchar
FETCH next FROM cur_columns_varchar INTO
@ColumnName , @IsNullAble , @DCName , @DCValue ,
@CCName , @CCValue , @Length , @ColumnType
WHILE ( @@FETCH_STATUS = 0 )
BEGIN
SET @sqlstr = ''
-- 默認值約束不為空
IF @DCName IS NOT NULL
SET @sqlstr = ' ALTER TABLE ' + @tableName + ' DROP CONSTRAINT ' + @DCName + ' ; '
-- 自定義約束不為空
IF @CCName IS NOT NULL
SET @sqlstr = @sqlstr + ' ALTER TABLE ' + @tableName + ' DROP CONSTRAINT ' + @CCName + ' ; '
-- 更改數據類型
IF @ColumnType = @varcharTypeId -- varchar
BEGIN
SET @sqlstr = @sqlstr + ' ALTER TABLE ' + @tableName + ' ALTER COLUMN ' + @ColumnName + ' NVARCHAR( ' + CAST ( @Length AS VARCHAR ) + ' ) '
IF @IsNullAble = 0
BEGIN
SET @sqlstr = @sqlstr + ' NOT NULL '
END
END
ELSE -- text
BEGIN
SET @sqlstr = @sqlstr + ' ALTER TABLE ' + @tableName + ' ADD TMP__ ' + @ColumnName + ' ntext; '
EXEC ( @sqlstr )
-- +CHAR(10)+'GO'+CHAR(10)
SET @sqlstr = ' UPDATE ' + @tableName + ' SET TMP__ ' + @ColumnName + ' = ' + @ColumnName
+ ' ;ALTER TABLE ' + @tableName + ' DROP COLUMN ' + @ColumnName
+ ' ;EXEC sp_rename ' + CHAR ( 34 ) + @tableName + ' .TMP__ ' + @ColumnName + CHAR ( 34 ) + ' , ' + CHAR ( 34 ) + @ColumnName + CHAR ( 34 ) + ' , ' + CHAR ( 34 ) + ' COLUMN ' + CHAR ( 34 )
END
SET @sqlstr = @sqlstr + ' ; '
-- 默認值約束不為空
IF @DCName IS NOT NULL
SET @sqlstr = @sqlstr + ' ALTER TABLE ' + @tableName + ' ADD CONSTRAINT ' + @DCName + ' DEFAULT ' + @DCValue + ' FOR ' + @ColumnName + ' ; '
-- 自定義約束不為空
IF @CCName IS NOT NULL
SET @sqlstr = @sqlstr + ' ALTER TABLE ' + @tableName + ' ADD CONSTRAINT ' + @CCName + ' CHECK ( ' + @CCValue + ' ); '
-- 執行
-- SELECT @sqlstr
EXEC ( @sqlstr )
FETCH next FROM cur_columns_varchar INTO
@ColumnName , @IsNullAble , @DCName , @DCValue ,
@CCName , @CCValue , @Length , @ColumnType
END
CLOSE cur_columns_varchar
DEALLOCATE cur_columns_varchar
DROP TABLE #PrimaryColumn
(
@tableName nvarchar ( 128 ) -- 表名
)
AS
DECLARE @varcharTypeId tinyint -- varchar數據類型編號
DECLARE @textTypeId tinyint -- text數據類型編號
DECLARE @ColumnName nvarchar ( 128 ) -- 系統列名
DECLARE @CType VARCHAR ( 1 ) -- 類型
DECLARE @IsNullAble char ( 1 ) -- 是否允許為空
DECLARE @Length int -- 欄位長度
DECLARE @ColumnType int -- 列類型
DECLARE @DCName nvarchar ( 128 ) -- 默認值約束名稱
DECLARE @DCValue nvarchar ( max ) -- 默認值約束表達式
DECLARE @CCName nvarchar ( 128 ) -- 自定義約束名稱
DECLARE @CCValue nvarchar ( max ) -- 自定義約束表達式
DECLARE @objectid int
DECLARE @sqlstr nvarchar ( max )
IF NOT EXISTS ( SELECT * FROM sys.tables WHERE name = @tableName )
BEGIN
RAISERROR ( ' 數據表不存在,請確認表名是否正確! ' , 16 , 1 )
RETURN
END
SET @objectid = OBJECT_ID ( @tableName )
-- 取得varchar, text類別編碼,名稱不能重複,可通過名稱查詢【已測試過】
SELECT @varcharTypeId = system_type_id FROM sys.types WHERE name = ' varchar '
SELECT @textTypeId = system_type_id FROM sys.types WHERE name = ' text '
-- 取得主鍵列名
SELECT COL_NAME (IC. object_id , IC.column_id) AS ColumnName
INTO #PrimaryColumn
FROM sys.index_columns AS IC
LEFT JOIN sys.indexes AS I ON I. object_id = IC. object_id AND I.index_id = IC.index_id
WHERE I.is_primary_key = 1
AND IC. object_id = @objectid
-- 更新類型
DECLARE cur_columns_varchar CURSOR STATIC FOR
-- 查找非主鍵varchar, text類型字段並找出相應默認值及約束
SELECT C.name AS ColumnName, C.is_nullable, D.name AS DCName, D.definition AS DCValue,
CK.name AS CCName, CK.definition AS CCValue, C.max_length, C.system_type_id
FROM sys.columns AS C -- 系統字段視圖
LEFT JOIN sys.default_constraints AS D ON D.parent_object_id = C. object_id AND D.parent_column_id = C.column_id -- 默認值視圖
LEFT JOIN sys.check_constraints AS CK ON CK.parent_object_id = C. object_id AND CK.parent_column_id = C.column_id -- 約束視圖
WHERE C. object_id = @objectid
AND (C.system_type_id = @varcharTypeId OR C.system_type_id = @textTypeId )
AND NOT EXISTS ( SELECT * FROM #PrimaryColumn WHERE ColumnName = C.name)
OPEN cur_columns_varchar
FETCH next FROM cur_columns_varchar INTO
@ColumnName , @IsNullAble , @DCName , @DCValue ,
@CCName , @CCValue , @Length , @ColumnType
WHILE ( @@FETCH_STATUS = 0 )
BEGIN
SET @sqlstr = ''
-- 默認值約束不為空
IF @DCName IS NOT NULL
SET @sqlstr = ' ALTER TABLE ' + @tableName + ' DROP CONSTRAINT ' + @DCName + ' ; '
-- 自定義約束不為空
IF @CCName IS NOT NULL
SET @sqlstr = @sqlstr + ' ALTER TABLE ' + @tableName + ' DROP CONSTRAINT ' + @CCName + ' ; '
-- 更改數據類型
IF @ColumnType = @varcharTypeId -- varchar
BEGIN
SET @sqlstr = @sqlstr + ' ALTER TABLE ' + @tableName + ' ALTER COLUMN ' + @ColumnName + ' NVARCHAR( ' + CAST ( @Length AS VARCHAR ) + ' ) '
IF @IsNullAble = 0
BEGIN
SET @sqlstr = @sqlstr + ' NOT NULL '
END
END
ELSE -- text
BEGIN
SET @sqlstr = @sqlstr + ' ALTER TABLE ' + @tableName + ' ADD TMP__ ' + @ColumnName + ' ntext; '
EXEC ( @sqlstr )
-- +CHAR(10)+'GO'+CHAR(10)
SET @sqlstr = ' UPDATE ' + @tableName + ' SET TMP__ ' + @ColumnName + ' = ' + @ColumnName
+ ' ;ALTER TABLE ' + @tableName + ' DROP COLUMN ' + @ColumnName
+ ' ;EXEC sp_rename ' + CHAR ( 34 ) + @tableName + ' .TMP__ ' + @ColumnName + CHAR ( 34 ) + ' , ' + CHAR ( 34 ) + @ColumnName + CHAR ( 34 ) + ' , ' + CHAR ( 34 ) + ' COLUMN ' + CHAR ( 34 )
END
SET @sqlstr = @sqlstr + ' ; '
-- 默認值約束不為空
IF @DCName IS NOT NULL
SET @sqlstr = @sqlstr + ' ALTER TABLE ' + @tableName + ' ADD CONSTRAINT ' + @DCName + ' DEFAULT ' + @DCValue + ' FOR ' + @ColumnName + ' ; '
-- 自定義約束不為空
IF @CCName IS NOT NULL
SET @sqlstr = @sqlstr + ' ALTER TABLE ' + @tableName + ' ADD CONSTRAINT ' + @CCName + ' CHECK ( ' + @CCValue + ' ); '
-- 執行
-- SELECT @sqlstr
EXEC ( @sqlstr )
FETCH next FROM cur_columns_varchar INTO
@ColumnName , @IsNullAble , @DCName , @DCValue ,
@CCName , @CCValue , @Length , @ColumnType
END
CLOSE cur_columns_varchar
DEALLOCATE cur_columns_varchar
DROP TABLE #PrimaryColumn