Recently I produced a website for hosting on a Linux box running with PHP5 and MySQL5. Well it now needs to move over to a Windows 2003 server with MS SQL as the DB and IIS as opposed to Apache.
- Install MyODBC
- Install SQL Server 2005 Express
- Using MS SQL Server Management create a new database. (right click on databases in the Object Explorer) 
- Use the following SQL Server SQL to create a link to your MySQL DB: - EXEC master.dbo.sp_addlinkedserver @server = N'MYSQL', @srvproduct=N'MySQL', @provider=N'MSDASQL', @provstr=N'DRIVER={MySQL ODBC 3.51 Driver}; SERVER=MySQLServerIP; DATABASE=Db_NAME; USER=MySQLUserName; PASSWORD=MySQLPassword; OPTION=3'- Execute the above 
- Use the following PHP script to get a list of tables to import: - $conn = mysql_connect('host','user','pass'); mysql_select_db('database',$conn); $SQL = "SHOW TABLES;"; $result = mysql_query($SQL, $conn); while($row = mysql_fetch_array($result)) print "SELECT * INTO SQLServerDBName.dbo.{$row[0]}<br /> FROM openquery(MySQL, 'SELECT * FROM `{$row[0]}`');<br /> ";
- Copy and paste the output from the above script into your SQL Server query window and execute it 
- All your data should now have been transferred across along with the table schemas 
Don’t forget to change all the references above to your correct database server settings.
Please note I have had some trouble with SQL Server not accepting 0000-00-00 00:00:00 in datetime fields set to not null in MySQL – set your datetime fields to accept null before exporting.
Also primary keys and auto_increment column attributes are not brought across either. So you will need to go into Server Management and manually re-add your auto_increment (Identity in SQL Server speak) and the primary key. It can also be done programmatically like this:
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_admin_accounts
    (
    account_id int NOT NULL IDENTITY (1, 1),
    username varchar(20) NOT NULL,
    passhash char(40) NOT NULL
    )  ON [PRIMARY]
GO
SET IDENTITY_INSERT dbo.Tmp_admin_accounts ON
GO
IF EXISTS(SELECT * FROM dbo.admin_accounts)
     EXEC('INSERT INTO dbo.Tmp_admin_accounts (account_id, username, passhash)
        SELECT account_id, username, passhash FROM dbo.admin_accounts WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_admin_accounts OFF
GO
DROP TABLE dbo.admin_accounts
GO
EXECUTE sp_rename N'dbo.Tmp_admin_accounts', N'admin_accounts', 'OBJECT'
GO
ALTER TABLE dbo.admin_accounts ADD CONSTRAINT
    PK_admin_accounts PRIMARY KEY CLUSTERED
    (
    account_id
    ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT
Because SQL Server doesn’t allow you to alter a pre-existing column to be an Identity (auto_increment) column you have to:
- Create a temporary table with an Identity column
- Allow arbitrary numbers to be inserted into the Identity column (includes previously inserted IDs apparently so you could end up with duplicates!)
- Move the data across to the temporary table
- Disallow inserting into the Identity column
- Drop the original table
- Rename the temporary table to the same name as the original
- Alter the Identity column to add the primary key
Wow! What a pain.