Kolon tipini değiştimek ya da büyüklüğünü arttırmak
Veri tipini değiştirmenin 2 yolunu anlatacağım.
Yöntem 1: SSMS üzerinde çok basit bir şekilde yapılabilir. Ama mevcut verinizin içeriğini ve sql server veri tiplerini çok iyi bilmeniz gerekir. Çünkü tip değişikliklerinde verinizi kaybedebilirsiniz.
Örnek olarak AdventureWorks2014 veritabanındaki Address tablosunu kullanacağım. Aşağıda Address tablosunun create script’ini görebilirsiniz.
USE [AdventureWorks2014] GO CREATE TABLE [dbo].[Address]( [AddressID] [float] NULL, [AddressLine1] [nvarchar](max) NULL, [AddressLine2] [nvarchar](max) NULL, [City] [nvarchar](max) NULL, [StateProvinceID] [float] NULL, [PostalCode] [nvarchar](max) NULL, [rowguid] [nvarchar](255) NULL, [ModifiedDate] [datetime] NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
Bu tabloda AddressLine1 kolonunun tipini nvarchar(max)’dan varchar(4000)’e dönüştürelim.
SSMS üzerinden Address tablosuna sağ tıklayıp aşağıdaki gibi design’ı seçiyoruz.
Açılan sayfada DataTypes kısmından aşağıdaki gibi AddressLine1 kolonunun tipini varchar(MAX)’a dönüştürüp sol üst tarafta altı çizili işarete tıklayıp yaptığımız değişikliğin script’ini alıyoruz. Burda script’e tıkladığınızda hata alırsanız çözümünü “Saving changes is not permitted hatasının çözümü” isimli makalemde bulabilirsiniz.
SQL Server’ın bu işlem için arka planda oluşturduğu script aşağıdaki gibi;
BEGIN TRANSACTION SET QUOTED_IDENTIFIER ON SET ARITHABORT ON SET NUMERIC_ROUNDABORT OFF SET CONCAT_NULL_YIELDS_NULL ON SET ANSI_NULLS ON SET ANSI_PADDING ON SET ANSI_WARNINGS ON COMMIT BEGIN TRANSACTION GO CREATE TABLE dbo.Tmp_Address ( AddressID float(53) NULL, AddressLine1 varchar(MAX) NULL, AddressLine2 nvarchar(MAX) NULL, City nvarchar(MAX) NULL, StateProvinceID float(53) NULL, PostalCode nvarchar(MAX) NULL, rowguid nvarchar(255) NULL, ModifiedDate datetime NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO ALTER TABLE dbo.Tmp_Address SET (LOCK_ESCALATION = TABLE) GO IF EXISTS(SELECT * FROM dbo.Address) EXEC('INSERT INTO dbo.Tmp_Address (AddressID, AddressLine1, AddressLine2, City, StateProvinceID, PostalCode, rowguid, ModifiedDate) SELECT AddressID, CONVERT(varchar(MAX), AddressLine1), AddressLine2, City, StateProvinceID, PostalCode, rowguid, ModifiedDate FROM dbo.Address WITH (HOLDLOCK TABLOCKX)') GO DROP TABLE dbo.Address GO EXECUTE sp_rename N'dbo.Tmp_Address', N'Address', 'OBJECT' GO COMMIT
Scipt’te gördüğünüz gibi yeni kolon tipimiz ile bir tablo oluşturdu ve bu tablonun başına Tmp_ koydu. Temp tablo ile karıştırmayın. Sadece geçici olarak bu tabloyu oluşturduğu için isminin başına Tmp_ ifadesini koydu. Daha sonra eski tablomuzdan select ile bütün verileri çekerek Tmp_Address tablosuna bütün verileri aktardı. Aktarım tamamlandıktan sonra gerçek Address tablosunu sildi ve silme işleminden sonra Tmp_Adress ismiyle oluşturduğu tablonun ismini Address olarak değiştirdi.
Aslında SSMS üzerinden sadece kolon tipini değiştirmemize rağmen arka planda SQL Server yeni bir tablo oluşturarak bu işlemi gerçekleştiriyor. Bence bu en güvenilir yöntem. Ama tabi öncelikle bu işlemi test ortamında yapmak lazım. Birde en önemlisi bu işlemi yapmadan önce veritabanının backup’ını almak şart.
Peki tablomuz çok büyükse bu işlemi nasıl yapacağız?
Bu yöntemle tek seferde tablodan select çekip tek seferde insert yaptığı için veritabanınızın log dosyasının olduğu diskte bu tablonun boyutunun en az 1.5 katı kadar yer olmasına dikkat edin. Eğer log dosyanızın olduğu diskiniz dolarsa işlem yarıda kalacaktır.
Büyük tabloları aktarmak için “Veritabanı file group yapısı ve büyük tablolarımızı başka bir file group’ta yeniden oluşturmak” isimli makalemi okumanızı tavsiye ederim.
Yöntem 2: Öncelikle tablonuza sağ tıklayarak aşağıdaki gibi create script’ini almanız gerekiyor.
Sonra aşağıdaki kodda ALTER COLUMN’dan sonraki kısma aldığınız create script’teki değişiklik yapmak istediğiniz kolonu alıp yapıştırıyorsunuz. Bunun nedeni değişiklik yaparken hata yapmadan sadece yapmak istediğimiz değişikliği yapmak.
Örneğin kolon normalde not null iken yanlışlıkla null olabilir gibi bir değişiklik yapmak istemeyiz. Amacımız sadece tip değişikliği.. Bu kopyalama işlemini yaptıktan sonra sadece yapmak istediğimiz değişikliği yapıp script’imizi çalıştırıyoruz. Örneğin aşağıdaki script’te [nvarchar](max)’nin başındaki N ‘ i silip [varchar](max)’ ye dönüştürebilirsiniz. Ama unutmayın bu verilerinizde bozulmaya sebep olabilir. O yüzden herzaman kolon değişikliği için 1.Yöntem’i izleminizi tavsiye ederim.
USE [AdventureWorks2014] GO ALTER TABLE [dbo].[Address] ALTER COLUMN [AddressLine1] [nvarchar](max) NULL GO
Veri boyutunu arttırmak:
Bu işlemin tip değişimi gibi bir tehlikesi yoktur. O yüzden yukarda anlattığım 2.yöntem’i kullanarak bu işlemi gerçekleştirebilirsiniz. Çok hızlı bir şekilde gerçekleşecektir.