pillinetwork hesabınızla giriş yapın.

MSSQL veritabanını MySQL'e Dönüştürme

Bir projemde MSSQL'den MySQL'e geçmek zorunda kalmam üzerine, internette çeşitli aramalar yaptım. Bu dönüşümü yapan bir çok program, script buldum. Programların bulabildiğim hepsi lisanslıydı, benim de verecek param yoktu. Ücretsiz olarak dağıtılan scriptlerin bazılarını ben çalıştıramadım, bazıları kendisi çalışmadı, bazıları da işimi görmedi. Bunun üzerine ASP'de kendim bir script oluşturdum ve ücretsiz olarak dağıtıyorum.

Bu yazımda sizlere scriptin çalışma mantığından bahsedeceğim ve en altta indirebilmeniz için bir link bırakacağım.

Öncelikle kullanıcıdan kaynak (Mssql) sunucu ve hedef (Mysql) sunucunun bilgilerini bir form yardımıyla alıyoruz. Aynı işlemi dosya düzenleme yoluyla da yapabilirlerdi ancak bu şekilde daha kolay olacağını düşündüm.

Akabinde bağlantı cümleciklerini oluşturuyorum.

Bir sonraki aşama ise kaynak veritabanındaki tüm tabloları listelemek oluyor.

1
2
3
4
5
6
7
8
9
10
11
12
tablolar = ""
set rs = mssqldb.execute("SELECT * FROM INFORMATION_SCHEMA.TABLES")
do until rs.eof
'Eğer tablo sistem tablosu değilse döngüde kullanmak için tablolar değişkenine virgül yardımıyla sıralıyoruz.
if left(rs("table_name"),3)<>"sys" then
tablolar = tablolar&rs("table_name")&","
end if
rs.movenext
loop
rs.close
set rs = nothing

Tablolarımızı yazdırdıktan sonra tüm tabloları işleme sokabilmek için for döngüsüne alıyoruz.

1
2
3
4
5
6
7
tablox = split(tablolar,",")
for k = 0 to Ubound(tablox)-1
tabloismi = tablox(k)
'işlemler burada yapılıyor.
next

Kodların anlatımında dıştan içe yöntem kullandım. Kabuk kabuk anlatıyorum. Bu nedenle yukarıdaki kodda döngüyü başlattım ve bitirdim.

Şimdi tablonun sütun sayısına göre bir döngü oluşturacağız. Bu döngü içinde Mysql'de tablomuzu ve sütunlarını oluşturacağız.

1
2
3
4
5
6
7
Set ks = Server.CreateObject("ADODB.RecordSet")
ks.open "select * from "&tabloismi&"",mssqldb,3,3
sayif = ks.fields.count
For i = 0 to sayif-1
Next

Bu noktada birkaç bilgilendirme yapayım. Bu döngü içerisinde sütunun ismini, veri tipini ve gerekirse uzunluğunu alacağız.

Sütunun ismi:

1
ks.fields(i).Name

Sütunun tipi:
1
ks.fields(i).Type

Sütunun uzunluğu:
1
ks.fields(i).DefinedSize

Sütun tipleri sayısal değer olarak geliyor. Bu sayısal değerleri birazdan göreceğiniz ifli koşullarla sql cümleciğinde kullanılabilecek tipe getireceğiz.
Sütun uzunluğu ise bir çok sütun tipinde kullanılmıyor. Ama kullanılıyor da olabilir çünkü tam anlamıyla hakim olduğumu söyleyemem.
Aynı şekilde bu üç değerin dışında birçok değer var, fakat bir çoğu için gerekli mi değil mi, nerede kullanılıyor kullanılmıyor bilmediğimden bu scripte eklemedim.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
ty = ks.fields(i).Type
uzunluk = ks.fields(i).DefinedSize
ty = cint(ty)
if ty = 3 then
nty = "int"
nuz = ""
elseif ty = 129 then
nty = "char"
nuz = "("&uzunluk&")"
elseif ty = 202 then
nty = "text" 'nvarchar
nuz = ""
elseif ty = 11 then
'nty = "ENUM(<a href="http://www.kodaman.org/etiket/">1</a>, <a href="http://www.kodaman.org/etiket/">0</a>)"
nty = "tinyint"
nuz = ("1")
elseif ty = 135 then
nty = "datetime"
nuz = ""
elseif ty = 131 then
nty = "int"'numeric
nuz = ""
elseif ty = 128 then
nty = "binary"
nuz = "("&uzunluk&")"
else
nty = "text"
nuz = ""
end if

Yukarıda verdiğim listeyi kısaltarak ekledim. Genel olarak mantığı anlamışsınızdır.

Veri tipleri ile ilgili bilgilendirmeler:
Mssql'deki BIT yani True/False veri tipini tinyint(1) olarak kaydediyorum. Normalde Mysql'de bu işlem ENUM ile yapılıyor. Fakat ENUM'a çevirdiğimiz zaman ASP dosyalarımızdaki bağlantı cümleciklerinde köklü değişiklikler yapmamız gerekecek.

Normal bağlantı cümleciğimiz şu şekilde:

1
select * from tablo where aktif = 1

Bu bize aktif sütunu True olan kayıtları getirir. ENUM tipine çevirdiğimiz zaman aktif = '1' şeklinde kullanmamız gerekiyor.
Eğer bağlantı cümleciklerinde zaten bu şekilde kullandıysanız veya sitenizi PHP ile yeniden kodlayacaksanız ENUM tipine geçmenizi öneririm.
Diğer değişikliklerse Numeric, nvarchar tiplerinde oldu. Nvarchar text olarak kaydedildi, numeric ise int olarak. Neden derseniz, kendi veritabanımda denedim bu şekilde başarıya ulaşamadım :)

Geriye kalan kodlarımıza devam edebiliriz. Şimdi tablomuzu ve sütunlarımızı oluşturacağız. Bununla ilgili bilgilendirmeleri kodun içinde yapacağım.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if i = 0 then
'i=0 durumunda birinci sütunda oluyoruz. Ve tablomuzu ilk sütunuyla birlikte oluşturuyoruz.
'Bu scripti birden fazla denemeyle oluşturduğum için tek tek Phpmyadminden tablo silmek ile uğraşmadım. Bu kod ile Mysql'de varolan tabloyu sildim. Sonra tekrar oluşturdum.
mysqldb.execute("DROP TABLE IF EXISTS `"&tabloismi&"` ")
'Eğer ki ilk sütunumuz sayısal bir değerse %90 ihtimalle otomatik artan bir değerdir. Belki otomatik artan değer olup olmadığını kodlarla bulabiliriz ama ben bilmiyorum henüz :)
if ty = 3 or ty = 17 or ty = 20 or ty = 5 or ty = 4 then
mysqldb.Execute("Create Table "&tabloismi&" ("&ks.fields(i).name&" "&nty&nuz&" NOT NULL auto_increment , PRIMARY KEY (`"&ks.fields(i).name&"`))")
else
'Eğer ilk sütunumuz sayısal değilse otomatik artan olmasına imkan yoktur.
mysqldb.Execute("Create Table `"&tabloismi&"` ("&ks.fields(i).name&" "&nty&nuz&") " )
end if
else
'i=0 olmadığı yani ilk sütun olmayan durumlarda Alter Table komutuyla tablomuza sütunları tek tek ekliyoruz.
mysqldb.Execute("alter table "&tabloismi&" add "&ks.fields(i).name&" "&nty&<a href="http://www.kodaman.org/etiket/nuz">&nuz&</a>)
end if

Ve böylelikle veritabanımızı oluşturmuş bulunuyoruz. Sütun tipleri ile ilgili problemleri olanlar olabilir, hemen belirtiyim; veritabanı konusunda çok çok iyi bir bilgiye sahip olduğumu söyleyemem. Bu kodlar ile kendi veritabanımı sorunsuz olarak oluşturdum. Eğer sizin veritabanınız düzgün bir biçimde aktarılmıyorsa ve yeterli bilgiye sahip değilseniz iletişime geçerseniz elimden geldiğince yardımcı olmaya çalışırım.

Artık sıra geldi verilerimizi aktarmaya!

Yukarıda olduğu gibi kodun içinde neyi ne amaçla yaptığımı anlatacağım.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Do While not ks.eof 'Hepiniz biliyorsunuz bunu :P
eklen = <a href="http://www.kodaman.org/etiket/deger-">
deger = </a>
'Hangi veritabanında hangi sütun olduğunu bilmiyoruz, dolayısıyla genel bir bağlantı cümleciği kullanmamız gerekiyor. Bu cümlecikte aşağıdaki "insert into" ile başlayan kod.
For i = 0 to sayif-1
'insert into kodunu "insert into tablo (sutun1,sutun2,sutun3) Values ('deger1','deger2','deger3')" şeklinde kullanıyoruz. Görüldüğü üzre son sütunda ve verisinde virgül kullanılmıyor. Bu nedenle aşağıdaki if kontrolünde son sütunsa virgül koymuyoruz.
if i = sayif-1 then
eklen = eklen&"`"&ks.fields(i).name&"` "
'Veri tipimiz datetime ise daha önceden belirlediğim Tarihcevir fonksiyonu ile Mssql deki tarihleri mysql biçimine çeviriyorum.
' 12.03.2010 01:20:56 'In MSSQL
' 2010-03-12 01:20:56: 'In MySQL
if cint(ks.fields(i).Type) = 135 then
a = Tarihcevir(ks.fields(i)&<a href="http://www.kodaman.org/etiket/------else------a--ks.fieldsi">)
else
a = ks.fields(i)&</a>
end if
deger = deger&"'"&Temizle(a)&"' "
else
'Son sütun olmadığı için gönül rahatlığıyla virgülleri ekliyorum.
eklen = eklen&"`"&ks.fields(i).name&"`, "
if cint(ks.fields(i).Type) = 135 then
a = Tarihcevir(ks.fields(i)&<a href="http://www.kodaman.org/etiket/------else------a--ks.fieldsi">)
else
a = ks.fields(i)&</a>
end if
deger = deger&"'"&Temizle(a)&"' , "
end if
next
'Ve kaydı tablomuza gönderiyoruz.
sql = "insert into "&tabloismi&" ("&eklen&") VALUES ( "°er&")"
mysqldb.execute(sql)
ks.movenext
s = s +1
Loop

Kodlarımın açıklaması bu kadar. Mantığı kavradıysanız eğer siz de farklı yollardan bu işe yarayan bir script yazabilirsiniz.

Kendi veritabanımı taşıdım demiştim, işte veritabanımın bilgileri:
19 tablo, 20,318 kayıt. Eksiksiz aktarım.

Bir not, mssql sunucunuz ve mysql sunucunuz aynı bilgisayar üzerinde olursa script timeout vermez. Eğer Local'de çalışırsanız tadından yenmez :)

Bu güzelim scripti indir

Yok bu hoşuma gitmedi başka bitane varmış onu indireyim. (Visual basicte yazılmış ve sadece orada kullanılan, mükemmel olduğunu düşündüğüm, mysql resmi sitesinde linki bulunan, çalıştırmayı beceremediğim dosya)

Spacer
Spacer
/* shibbytr yazdı. 16 Mart 2010 11:52. 5 yorum var */

Yorumlar

mySQL'de de bit türünde veritipi bulunuyor tinyint veya enum ile uğraşmanıza gerek yok. SQL cümlesinde true veya false ifadelerini kabul eden bir alandır kendisi. Ayrıca mySQL bit alanını recordsete yüklediğinizde asp ile mantıksal sınamaya asp'nin kendi deyimleriyle alabilirsiniz. (yani aspdeki true ve false deyimleri) bu veri uygunluğu (boolean) asp tarafından otomatik olarak sağlanıyor.

Mysql'deki bit türünün mssql'deki türle eşdeğer olduğunu bilmiyordum. Daha doğrusu ASPdeki sorgulamayla eşdeğer olduğunu bilmiyordum. Mysql'de bir kere bit türünü kullanmıştım fakat çözememiştim ne olduğunu. Yazımda da belirttiğim gibi, veritabanlarına çok hakim değilim. Scriptte güncelleme yaparım, bu veri türünü Bit olarak kaydetmesini sağlarım. Teşekkürler.

2. linkte verdiğiniz oldukça güzel. index, precision, scale gibi öğeleri de dikkate almış. ayrıca dönüşüm tiplerini de oldukça geniş tutmuş. çalıştırırken ne hatası aldınız acaba?

/* herkes kendi beyninin akım şiddeti ölçüsünde aydınlanır. */

Açıkçası çalıştıramadım, visual basic bilgim yok. Bu dönem dersini almaya başladık. Dersi veren öğretim görevlisine dosyayı gönderdim, oda çalıştıramadığını söyledi. Keşke gerekli ayarları textboxlar şeklinde isteyen bir exe haline getirselermiş. Kullanımı çok daha kolay olurdu.

Herkese dönüşüm ikinci linkteki dosyayı öneriyorum, ASP bilgisini geliştirmek isteyenlere de kendi scriptimi öneriyorum. Tabii ki basit bir veritabanını benim yazdığım script ile de dönüştürebilirsiniz. En azından ben denedim çalıştırdım kendi scriptimi :)

Çeşitli veritabanı türlerinden mySQL'e geçiş için, mySQL'in kendi aracı var. mySQL Migration Toolkit aracı, diğer veritabanlarını verileri ile birlikte otomatik olarak mySQL'e dönüştürebiliyor.

üye olunpillinetwork sitelerine yorum ekleyebilmek ve daha fazlası için, üye olun ya da giriş yapın.

Bu Yazıyı Tutanlar

Bu yazıyı rapor et. Kural dışı içeriğe rastladığınızda editörlerimize rapor ederek müdahale edilmesini sağlayabilirsiniz. (Hangi durumlarda rapor edebilirim?)

Bu site

Nokta ve pilli ortak yapımı olan kodaman.org hep birlikte içerik üretip gelirini yazarları ile paylaştığımız kolektif bir kod yazarları blogudur. Siz de katılabilirsiniz.

pilliilan

son yorumlar

arama

pillinetwork