Querying MySQL from SQL Server using linked server

SQL Server has interesting feature calles Linked Servers. It’s about linking other databases to SQL Server and using their data like it’s local. There are many powerful open-source systems written on PHP and they are mostly using MySQL as database. This blog post shows how to link MySQL database to SQL Server and how to use linked server in SQL queries.

What is linked server?

Linked server in MSSQL is some other database server connected to given one, making it possible to query and manipulate data in other databases. By example, we can link some MySQL database to MSSQL and use it almost like any other database on MSSQL.

Architure of SQL Server linked servers
 
Image is taken from MSSQL 2019 documentation page
Linked Servers (Database Engine)

Although communication with linked servers goes through OLE DB providers, there is also OLE DB provider for ODBC and we can use it if our external database doesn’t have OLE DB provider.

NB! Linked server is available for whole SQL Server instance. It means that all SQL Server databases can use linked server to retrieve data.

Linking MySQL to SQL Server

Adding linked server and configuring connection setting is not always easy and straightforward.

To get MySQL linked to SQL Server I needed to create ODBC DSN for MySQL (I named it as MySQLCrm). Before going to next steps, make sure that ODBC data source works.

Follow these steps to link MySQL to SQL Server:

  1. Run SQL Server Management Studio (SSMS)
  2. Connect to your server
  3. Expand Server Objects node from tree at left
  4. Right-click on Linked Servers
  5. Select New Linked Server…

You should see the following dialog (or bit different but the idea remains the same).

MySQL linked server settings

NB! Pay extra attention to what you insert to this dialog. With this set of data I made link work. I tried different values and if something is one millimeter wrong then connection fails. It’s damn sensitive dialog.

Connection string to MySQL database should be like shown here:

DRIVER=(MySQL ODBC 8.0 Unicode Driver); SERVER=localhost; PORT=3306; DATABASE=crmlinked; USER=crmuser; PASSWORD=crm_user_password; OPTION=3;

Also pay attention to OPTION=3 – without this I got only errors back when connecting to linked server.

Try to save by clicking OK and see if you can browse to linked server. If you get errors then right-click on server and select properties. Keeping the dialog open, move to Server Options page. Set RPC and RPC Out settings to True.

MySQL linked server options

I’m still not very sure what are these options doing but some of those who had issues with link to MySQL made it work after setting RPC-s to true.

To make querying actually work, we need one more little change that affects whole OLE DB provider and therefore all connections using it. Open Providers node under Linked Servers, right-click on MSDASQL (this is OLE DB provider for ODBC data sources) and select properties.

Configuring OLE DB data-source for ODBC

Check the box before Level Zero only and click OK to save changes.

Querying data from linked server

Querying linked databases is actually easy. Here’s the customers table from crmlinked database in MySQL. This database is linked to my SQL Server.

Customers table in MySQL database

Syntax for querying linked server is a little bit different from what we usually write on SQL Server. We need to use four-part names: server.database.schema.table. As there’s no schemas on MySQL and connection string specifies database name, then we can leave these out like shown here.

select * from MYSQLCRM...customers

Running this query from SSMS gives the following output. It’s the same data that is in MySQL customers table.

Query results from linked MySQL server

Of course, we can also write more complex queries. Everything that ODBC can handle is okay.

Mixing data from local and linked server

Tables from linked server are not totally isolated from local database tables and views. We can also mix data from local and linked server.

Customers table on SQL Server

To demonstrate mixed query over local and linked tables let’s write simple query to get all customers from local table and their credit ratings from linked table.

SELECT
    c.FirstName,
    c.LastName,
    crm_c.credit_rating as CreditRating
FROM 
    Customers c
    LEFT JOIN MYSQLCRM...customers crm_c ON
        c.ssn = crm_c.ssn
ORDER BY
    crm_c.credit_rating,
    c.LastName,
    c.FirstName

Running this query gives us the following output.

Results of mixed query over local and linked server data

As Mark is not present in MySQL database (suppose he is new customer in e-shop and sales department doesn’t have him yet in their CRM system) then he doesn’t have credit rating available. Credit ratings for John and Mary are coming from MySQL in current case.

Using OPENQUERY() to execute query in linked server

The examples above make all data processing on SQL Server. It can be very unoptimal if there’s a lot of data in linked server’s tables. We may want – or usually want – to process some data in linked server before SQL Server starts local processing. For this we have OPENQUERY().

Here’s the example of using OPENQUERY() function in mixed query. We have to specify linked server name and SQL query to run in linked server when calling OPENQUERY(). The query in red is executed in MySQL server and results are read to SQL Server for further processing.

SELECT
    c.FirstName,
    c.LastName,
    crm_c.credit_rating as CreditRating
FROM 
    Customers c
    LEFT JOIN OPENQUERY(MYSQLCRM, '
            SELECT
                c.credit_rating
            FROM
                customers p
                left join loyalty_points lp on
                    c.customer_id = lp.customer_id
            WHERE
                lp.points > 1000
        ') crm_c ON
        c.ssn = crm_c.ssn
ORDER BY
    crm_c.credit_rating,
    c.LastName,
    c.FirstName

OPENQUERY() is great way to optimize and speed up mixed queries by running more complex queries over linked server data in linked server.

Wrapping up

Linked servers is powerful feature of SQL Server making it easy for us to use data from external servers. There are two ways to write queries using data from linked servers – direct queries that do all processing on SQL Server and OPENQUERY() that lets us do some processing in remote server. Linked server is integration and therefore using it needs extra care. Planning and performance measuring are must-be activities when planning to use linked server.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    4 thoughts on “Querying MySQL from SQL Server using linked server

    Leave a Reply

    Your email address will not be published. Required fields are marked *