Çarşamba Eyl 8
Mar
15/10
Mssql2Mysql script bilgileri
Last Updated on Pazartesi, 15 Mart 2010 09:12
Written by Güven Atbakan
Pazartesi, 15 Mart 2010 09:12


Bu yazımda sizlere scriptin çalışma mantığından  bahsedeceğim ve kod açıklamalarını yapacağı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.

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.

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.

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:

ks.fields(i).Name

Sütunun tipi:

ks.fields(i).Type

Sütunun uzunluğu:

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.

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(“”1″”, “”0″”)”
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:

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.

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&”"&nuz&”")
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.

Do While not ks.eof ‘Hepiniz biliyorsunuz bunu :P
eklen = “”
deger = “”
‘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)&”")
else
a = ks.fields(i)&”"
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)&”")
else
a = ks.fields(i)&”"
end if
deger = deger&”‘”&Temizle(a)&”‘ , ”
end if
next

‘Ve kaydı tablomuza gönderiyoruz.
sql = “insert into “&tabloismi&” (“&eklen&”) VALUES ( “&deger&”)”
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)

Paylaş
  • Add to favorites
  • Print
  • email
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • FriendFeed
  • Live
  • Twitter
  • Yahoo! Bookmarks
  • MySpace
  • RSS
  • PDF

2 Yorum

  • At 2010.04.23 22:01, Alper Odabaş said:

    Tebrikler güven güzel bir paylaşım…

    • At 2010.04.23 23:01, Güven Atbakan said:

      Teşekkür ederim Alper Hocam.

      (Required)
      (Required, will not be published)

      Pardus

      Pardus... Özgürlük İçin... Özgürlük için Pardus...