Issue calling a MySQL stored procedure (with params) via a linked server (SQL Server 2005) using OPENQUERY syntax - mysql

I'm having issues when trying to call a MySQL (5.0.77) stored procedure with parameters, via a linked server (SQL Server 2005) using the OPENQUERY syntax.
The MySQL stored procedure returns a result set, and when I use the 'EXEC ... AT ...' syntax the call works fine, e.g...
EXEC('CALL my_stored_proc(''2009-10-07'',''2009-10-07'');') AT MySQLSERVER;
The limitation of using 'EXEC ... AT ...' means I can't insert the result set into a temporary table in SQL Server, which is ultimately what I want to do. Which led me to trying the OPENQUERY syntax...
SELECT * FROM OPENQUERY(MySQLSERVER,'CALL my_stored_proc(''2009-10-07'',''2009-10-07'');')
...But this fails, and returns...
Msg 7357, Level 16, State 2, Line 1
Cannot process the object "CALL my_stored_proc(''2009-10-07'',''2009-10-07'');". The OLE DB provider "MSDASQL" for linked server "MySQLSERVER" indicates that either the object has no columns or the current user does not have permissions on that object.
Which is strange, given that the 'EXEC ... AT ...' call didn't complain about permissions. The following calls all work fine...
EXEC('SHOW TABLES;') AT MySQLSERVER;
SELECT * FROM OPENQUERY(MySQLSERVER,'SHOW TABLES;');
CREATE TABLE #tmpTest (
[table] varchar(255) null
);
INSERT INTO #tmpTest ([table])
SELECT * FROM OPENQUERY(MySQLSERVER,'SHOW TABLES;');
SELECT * FROM #tmpTest;
DROP TABLE #tmpTest;
So my question is, how can I make a call to a MySQL stored procedure, via a linked server, and store the result set in a temporary table in SQL Server? Either by using the 'EXEC ... AT ...' syntax, or by solving the object/permissions error when using the OPENQUERY syntax.
Any help would be greatly appreciated!

You need to enable "Ad Hoc Distributed Queries" on the SQL Server. This is not enabled by default, for security reasons. Most of the time, the "do not have permission" errors are related to this one.
Execute this on the SQL Server, and then try again your code:
EXEC sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
EXEC sp_configure 'Ad Hoc Distributed Queries', 1;
GO
RECONFIGURE;
GO
I hope it helps.

I tried the fix to configure "Ad Hoc Distributed Queries" but was still getting this same error:
"The OLE DB provider "MSDASQL" for linked server "MyMySQL" indicates
that either the object has no columns or the current user does not
have permissions on that object."
I am attempting a simple remote SELECT query against a linked MySQL database.
In my case, the query I was attempting looked like this. Pay attention to the number of lines used:
SELECT * FROM OPENQUERY
([MyMySQL],
'
SELECT
ID as ISSUE_ID, etc..
The fix was to remove the newline after the opening single-quote. Simple, huh? But not obvious.
The working code shown below:
SELECT * FROM OPENQUERY
([MyMySQL],
'SELECT
ID as ISSUE_ID, etc..
Hope it helps!
Rob

I realize this a pretty old post, but my problem was similar to Rob's in that the SQL within the OPENQUERY doesn't take line breaks as whitespace the same way SQL server does.
i.e. Laying out my query as follows:
SELECT
*
FROM
OPENQUERY(LINKEDSERVER, '
SELECT
SomeField
FROM
SomeTable
')
I needed to have spaces as if it were written on one line (using _ as a visible space for demonstration):
SELECT
*
FROM
OPENQUERY(LINKEDSERVER, '
SELECT_
SomeField_
FROM_
SomeTable
')

Related

sqlcmd on Azure SQL Data Warehouse - SqlState 24000, Invalid cursor state after INSERT statement

I am working on a script to reload a table using SQLCMD on Linux connecting to an Azure SQL Data Warehouse database.
After the INSERT statement completes, the next statement fails (but does not end the sqlcmd execution) with the "warning"
insert into
schema.table_temp
(
...list of columns
)
select
...list of columns
from
schema.table
;
GO (COMMENT--> in script, but not echoed in log.)
(0 rows affected)
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES t WHERE TABLE_TYPE = 'BASE TABLE' and TABLE_SCHEMA = 'schema' AND TABLE_NAME = 'table_nox' )
DROP TABLE schema.table_nox
;
GO (COMMENT--> in script, but not echoed in log.)
SqlState 24000, Invalid cursor state
The script continues to run with each subsequent batch getting the same
SqlState 24000, Invalid cursor state "warning"
If I comment out the INSERT statement, the script runs without warning as expected. I speculate the INSERT statement is not closing a cursor and then subsequent commands get the warning which should really be considered an eror and end the execution. (I have the -b flag on in the sqlcmd invocation.)
Is my only solution to break the script into multiple parts?
this seems to be an issue with the ODBC Driver that is used by sqlcmd under the hood. Can you confirm if you see this issue with Azure SQL DB? It would also be good to see your odbc.ini and odbcinst.ini files. Can you share those out?
In the meanwhile, I would like to recommend a couple of very cool Node.js command line tools that are more suited for Linux and Mac environments:
SQL-CLI
Cheetah
Thanks,
Meet
I faced similar issue and adding GO between two statements helped me.
We had the same issue. When performing INSERT via a SELECT it resulted in a (0 rows affected) response and a invalid cursor state error. Adding SET NOCOUNT ON at the start of the script worked for us. As #meet-bhagdev has already pointed out it looks like a driver issue.

Sql Server sp_send_dbmail linked mysql server error

execute msdb.dbo.sp_send_dbmail
etc etc
#query = 'select * from Mysql...MemberRef4 as oi where oi.MemberId = 133363 '
The above is a query that I plugged into an existing working send mail method. MySql is a linked MySql database. I CAN run this query without any errors, correctly, by selecting the query code and F5. I am running this code and other MySql code joins with SqlServer and other linked servers - without any errors, including views/procs/etc.
However, the sp_send_dbmail method fails with :
Msg 22050, Level 16, State 1, Line 0
Failed to initialize sqlcmd library with error number -2147467259.
Note: this is the first time I'm trying to put MySql queries in sp_send_dbmail
Any help please. I really don't want stored procs that create temp tables/etc :(

Invalid descriptor index on LAST_INSERT_ID after insert

Strange situation with my ODBC code ( called from a C library ). Basically, I have the following sequence of events:
Create insert statement ( just a string )
Call SQLPrepare with that insert statement string
Bind the various parameters ( column values ), using
SQLBindParameter
Call SQLExecute to insert the row ( this works, by the way, as I can
see the row in the MySQL DB )
Create "select last_insert_id()" statement string
NOTE: if in SQL Server mode, we would create a "select ##identity"
statement
Bind column using SQLBindCol - this is where I get the "Invalid
descriptor index" error
NOTE: if in SQL Server mode, this works fine, with no error
Call SQLExecDirect to get the last insert id - this never happens
because of SQLBindCol error
Does the standard MySQL ODBC connector require something special in this situation? Does anyone have an ODBC example of this type of "insert" then "get last insert id" behavior? Maybe I need to call "SQLPrepare" before step 6 ( where I bind the column )? Another way to ask this: Should there be an SQLPrepare call for each SQLExecute or SQLExecDirect call?
I know it works directly in SQL, so the problem is my C ODBC code.
Thanks.
For those who are interested, I ended up changing the above steps by adding an SQLPrepare call between creating the "select last_insert_id()" ( step 5 ) and calling SQLBindCol ( step 6 ). Not sure if that would work for others, but it seems to be working rather well for me.
As for research, I looked all over the place online and never found a really good or clear answer. Most comments were about the SQL involved, not ODBC. And the references to ODBC were vague and did not seem to apply to my situation, from what I could see.
My assumption is that the SqlServer ODBC driver I am using handles the missing prepare statement differently ( maybe even better, but that is debatable ) than my MySql ODBC driver.
SQL Server ODBC driver was the one provided by Easysoft
MySql ODBC driver was the one provided with the standard CentOS install of MySql
Hopefully this will help people. Obviously, if people have a better idea, please tell us.

How do you get the ouput from an EXEC statement into a variable (calling procedure on mysql linked server)?

I am able to call a procedure on a linked server (MySQL) from Sql2k5. The procedure returns a single row, single column:
declare #Statement nvarchar(200)
set #Statement = 'call database.procedure(''some string'');'
exec (#Statement) at [linkedserver]
... results:
some string
What I need now is to set a variable to the value returned from the procedure
I found a somewhat related post here.
but when I try to insert the executed results:
insert into sometable exec (#Statement) at [linkedserver]
I get this error:
OLE DB provider "MSDASQL" for linked server "linkedserver" returned message "[MySQL][ODBC 5.1 Driver]Optional feature not supported".
Msg 7391, Level 16, State 2, Line 3
The operation could not be performed because OLE DB provider "MSDASQL" for linked server "linkedserver" was unable to begin a distributed transaction.
Is there a way to get around this, or a much better way to get at those results?
Thanks,
Linked servers are a real pain, especially when metadata gets screwed up. An “insert” is a distributed transaction no matter if you use BEGIN/COMMIT TRAN though (inserts cause log usage). Have you tried OPENQUERY yet? Or try these ideas:
http://www.sqlservercentral.com/Forums/Topic714869-338-1.aspx#bm716699
Note the provider and the linked server options in the following link:
http://www.infi.nl/blog/view/id/4/How_To_MySQL_as_a_linked_server_in_MS_SQL_Server

Delete all procedures except those which contain a string in their name

I want to drop a lot of SPs from my SQL Server database. However, I want to write "Delete all procedures except those which contain a certain string in their name".
How can I do this? I am using SQL Server 2008 R2.
Thank
What about:
SELECT 'DROP PROCEDURE ' + name
FROM sysobjects WHERE xtype = 'U' AND
name LIKE 'usp_%' -- Here you'll define your criteria
After running this, you just need to execute this command output.