Problems with sp_addlinkedserver in SQL Server 2000 - sql-server-2008

I'm having a bit of a problem with moving specific data from one server running SQL Server 2000 (A) and another running SQL Server 2008 (B). I'm writing a script according to customer specifications which is to be executed on A, populating tables in B with data. However, I can't seem to get the server link to work.
-- Bunch of declarations here
EXEC sp_addlinkedserver #server = #ServerName,
#srvproduct = #ServerProduct,
#provider = #ProviderString,
#datasrc = #RemoteHost
-- Data migration stuff here
EXEC sp_dropserver #ServerName
Now if I run the script in its entirety I get an error saying:
Msg 7202, Level 11, State 2, Line 55
Could not find server 'remoteServer'
in sysservers. Execute
sp_addlinkedserver to add the server
to sysservers.
However, if I highlight only the sp_addlinkedserver part and execute that, there is no error and I can highlight the rest of the script and run it. What am I missing here?
Please help!
PS. If backup-restore was an option, I would have done that already.

The problem is that SQL Server is trying to validate the code before it runs it. To show that, try putting one of your commands in EXEC(). Try putting a GO after the sp_addlinkedserver command.

Related

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 :(

How to prevent ADO from altering my SQL command text?

i am running a MERGE statement against an SQL Server 2008 R2 database (which is in 2008 compatibility mode).
The exact merge statement SQL is irrelevant, but here is an example of a MERGE statement:
MERGE Users
USING (VALUES
('{77410DC5-7A3E-4F1A-82C6-8EFB3068DE66}')
) AS rows(UserGUID)
ON Users.UserName = rows.UserName
WHEN NOT MATCHED BY SOURCE THEN
DELETE; --always end MERGE with semi-colon
When executing this statement from SSMS, or from a client PC running Windows 7, it executes correctly.
But when my software is running on a client PC that is Windows XP or Windows Server 2003 R2, the sql CommandText is being altered before reaching the server. In the SQL Server Profiler, i can see the SQL being executed is:
exec MERGE Users
USING (VALUES
('{77410DC5-7A3E-4F1A-82C6-8EFB3068DE66}')
) AS rows(UserGUID)
ON Users.UserName = rows.UserName
WHEN NOT MATCHED BY SOURCE THEN
DELETE; --always end MERGE with semi-colon
Which is not valid SQL, and SQL Server throws the error:
Incorrect syntax near the keyword 'MERGE'
You can confirm that it is invalid SQL by trying to execute it against your SQL Server 2008 R2 database.
Peter Boulton reported the same issue on the Microsoft forums:
SQL MERGE syntax works with Win7 SP1 client but fails with earlier platforms
I believe ADO parses the SQL before it sends it to the server. The data access components were updated for Win7 SP1 and also WinServer 2008 R2. However, I believe XP SP3's data access components predate SQL Server 2008.
That's why the SQL works from Win7 SP1 but not from XP.
My 'solution' was to wrap the SQL in an EXEC so that ADO allows it through, as in:
EXEC('MERGE....etc.')
His hack certainly works, change:
MERGE Users ...
into
EXEC('MERGE Users' ...)
but i'd like to come up with the real solution. I don't know who in the chain is responsible for altering my command text:
ADO -> OLEDB -> SQLOLEDB -> SQL Server
but i want them to stop.
How do i, through ADO, specify my command text, and have SQLOLEDB not modify it?
Right now my code is1:
String sqlCommandText = "MERGE Users" //snip;
int recordsAffected;
connection.Execute(
sqlCommandText,
out recordsAffected,
adCmdText | adExecuteNoRecords);
i do not see any ExecuteOptionEnum, or CommandTypeEnum to tell ADO, and underlying providers, to treat the text as raw.
For now the fixup hack is:
sql = "MERGE Users" ...
ExecuteNoRecords(connection, sql);
with the modified helper:
int ExecuteNoRecords(Connection connection, String sql)
{
//20130611: Fix bug in ADO that mangles/breaks SQL it doesn't understand (e.g. MERGE on Windows XP)
String obfuscatedCommandText = 'EXEC(' + QuotedStr(sql)+ ')';
int recordsAffected;
connection.Execute(obfuscatedCommandText, out recordsAffected, adCmdText | adExecuteNoRecords);
return recordsAffected;
}
Update: A better workaround hack
Rather than wrapping the entire statement in EXEC(...), i found a safer trick to defeating ADO is to precede the statement with a comment. Even an empty comment will do:
--
MERGE Users
USING (VALUES ...
In reality you will want to have some text explaining that the empty comment line is critical to making the query work:
--Leading comment to thwart ADO from mangling MERGE on Windows XP/2003R2
MERGE Users
USING (VALUES ...
Since there is no solution, and ADO (while not dead) is done, the hack is the answer.
Never issue a MERGE statement without a leading comment line:
--Dummy leading comment line to thwart ADO from mangling MERGE on Windows XP/2003R2
MERGE Users
USING (VALUES ...

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

OLE DB provider "Microsoft.Jet.OLEDB.4.0" for linked server "(null)"

ERROR MSG: The requested operation could not be performed because OLE DB provider "Microsoft.Jet.OLEDB.4.0" for linked server "(null)" does not support the required transaction interface.
I am stucked finding solutions for this error (see ERROR MSG).
Here is part of my code:
.....
INSERT INTO OPENROWSET('Microsoft.Jet.OLEDB.4.0', 'Excel 8.0;
Database=C:\Folder\file_output.xls',
'SELECT * FROM [Sheet1$]')
SELECT FROM FIELD1, FIELD2, FIELD3 dbo.MY_TABLE
WHERE TRANS_ID = 1
ORDER BY CTRL_NO ASC
.....
The above code is contained inside an SP... This is the last SP that is run in a series of SP calls.
Here is the chain/flow of execution: SP1->SP2->SP3->SP4 (assuming SP4 contains the above code)
But an error occurs as what the ERROR MSG suggests during the entire execution flow.
Here are the 2 scenarios that I've tried to test/trace the error.
- Run the the chain of SPs ----> result: error occurs
- Comment/Remove SP4, then run SP1->SP2->SP3 only. Then separately execute SP4. ----> result: okay
PLS. NOTE:I need to execute the SPs in flow.
There is no web/any front-end except SP1 is executed through SQL runner
I now wonder if this is a bug in MS SQL Server 2008 or I'm missing something.
If my question is still vague, kindly ask me for clarification. Thanks.
Try to check "Non transacted updates" option in "Server objects - Linked servers - Providers - Microsoft.Jet.OLEDB.4.0" properties. Maybe you will need to restart your sql server.

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

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
')