I should take a step back and advise you do not use a linked server if possible and instead use openrowset in MSSQL for accessing a remote MySQL server because a linked server will gather all the results and filter them locally in tempdb, whereas with openrowset you can filter server side using the remote server rdbms syntax. Also in my case it was only two servers and one database on each, so I did not require a cursor. That aside, here is what I think you are asking me:
- on the mssql server, install visual c++2010 runtimes if they are not already installed.
- install mysql odbc connector drivers ( version 5.1 64-bit in this example ) that match your sql server architecture
MySQL ODBC 5.1 64-bit
Enable ad-hoc distributed queries in the mssql instance
sp_configure 'show advanced options', 1;
RECONFIGURE;
GO
sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;
GO
Then basically the same thing in your procedure.
USE [whatever_database_name_here]
GO
/****** Object: StoredProcedure [dbo].[getRemoteData] Script Date: 03/15/2019 16:54:05 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE [dbo].[getRemoteData]
-- default bounds for epoch time ( mysql timestamp datatype )
@pdate1 date = '1970-01-01',
@pdate2 date = '2038-01-19'
AS
BEGIN
SET ARITHABORT ON;
SET ANSI_WARNINGS ON;
SET NOCOUNT ON;
DECLARE @dbname VARCHAR(255) = '';
DECLARE @qry VARCHAR(8000) = '';
DECLARE @cur_x CURSOR;
IF OBJECT_ID('tempdb..#tmp0') IS NOT NULL DROP TABLE #tmp0
CREATE table #tmp0 (
dbname varchar(255) not null,
your varchar(255) not null,
fields varchar(255)
);
SET @cur_x = CURSOR FAST_FORWARD FORWARD_ONLY FOR
SELECT q.dbname
FROM OPENROWSET('MSDASQL'
,'Driver={MySQL ODBC 5.1 Driver};Server=172.16.0.22;port=3306;Database=any_database_here;User=your_user;Password=your_password;Option=3;'
,'SELECT DISTINCT SCHEMA_NAME AS `dbname`
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME NOT IN (''information_schema'', ''performance_schema'', ''mysql'',''sakila'')
ORDER BY SCHEMA_NAME') q ;
OPEN @cur_x
FETCH NEXT FROM @cur_x into @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN
SET @qry = 'INSERT INTO #tmp0
SELECT ''' + @dbname + ''', q.* FROM OPENROWSET(''MSDASQL''
,''Driver={MySQL ODBC 5.1 Driver};Server=172.16.0.22;port=3306;Database=' + @dbname + ';User=your_user;Password=your_password;Option=3;''
,'' select t0.your, t1.fields from this_table t0
join that_table t1 on t0.fk_id = t1.id
where cast(' + @pdate1 + ' as DATE) >= CAST(t0.from_dt as DATE) and cast(' + @pdate2 + ' as DATE) <= CAST(t0.to_dt as DATE) '') q';
EXEC(@qry);
END;
FETCH NEXT FROM @cur_x into @dbname
END;
CLOSE @cur_x;
DEALLOCATE @cur_x;
select * from #tmp0;
END
Then you would call the mssql stored proc in koolreport in your setup.
exec getRemoteData @pdate1 = '2019-03-14', @pdate2 = '2019-03-15'
Hopefully you dont need to adjust any timeouts and your sql is fast because cursors unfortunately are not, but I coded this one to be optimized and run as quick as possible with forward only.
thx
-d