How to get list of databases from a linked server - sql-server

I have to look up for results on linked servers' databases. First I should know what dbs are available on a linked server. I tried to use the below query but gives an error.
What would be the proper way?
...
set #base_query_db_list =
'
select
''#server'',
name,
database_id,
create_date
from #server.sys.databases
'
set #server = '[linked_server_name]'
set #query_db_list = replace(#base_query_db_list, '#server', #server)
insert into #db_list
EXECUTE sp_executesql #query_db_list
...
Error:
Msg 208, Level 16, State 1, Line 2
Invalid object name '[linked_server_name].sys.databases'.

Related

Linked SQL Server - Pass a use command or define default database

I have a set of SQL queries that need to be run against 3 databases, they are stored on 2 different servers that have been linked.
All 3 databases have the the exact same tables and tables name, however the database names are different.
The queries have been written and all use just table names not the full database.dbo.table syntax so I can't use an automated find and replace on "linked.database1" to "linked.database2"
All the queries will always be executed through one server "Server1"
I'm trying to come up with a method of passing the queries to one of the linked servers but have a "use" command go through as it means I only have to change the database in the "use" line.
So far I have tried the following from Server1:
Select * from [Linked].Database.DBO.Table - Successful
Exec ('Select * from [Linked].Database.DBO.Table') - Successful
Direct on Server2 (using the account the linked server operates on):
EXEC ('Use Database; SELECT * from Table') - Successful
So with these above three I can ascertain
The login on Server1 can reach the databases needed and can access the data with a basic select and when passed with and Exec command.
The account on Server2 can run the Exec command and passing the "Use Database" line with Exec works on Server2.
However when I try using the below:
Select * from openquery ([Linked], 'Exec (Use Database; Select * from Table)')
I get the following error:
OLE DB provider "SQLNCLI10" for linked server "172.20.11.123" returned message "Deferred prepare could not be completed.".
Msg 8180, Level 16, State 1, Line 7
Statement(s) could not be prepared.
Msg 102, Level 15, State 1, Line 7
Incorrect syntax near ')'.
Msg 156, Level 15, State 1, Line 7
Incorrect syntax near the keyword 'Use'.
Have I messed up the syntax anywhere in the OpenQuery or can the USE command never be passed through OpenQuery.
If what I'm trying to do with OpenQuery and USE isn't possible then is there a way of passing the database you want the OpenQuery run against in the statement?
Or as a second thought, is there a way of putting together the Linked Server account so that it uses a particular database as its default database?
No, the way to do this, as far as I can tell, if you know which database you need to execute against:
DECLARE #database sysname = N'Database1';
DECLARE #sql nvarchar(max) = N'SELECT * FROM dbo.Table;';
DECLARE #exec nvarchar(4000) = N'[Linked].'
+ QUOTENAME(#database) + N'.sys.sp_executesql';
EXEC #exec #sql;
I'm not quite sure what this was trying to accomplish:
Select * from openquery ([Linked],
'Exec (Use Database; Select * from Table)')
But if you take out from that what you're trying to tell [Linked] to EXEC, it's this:
Exec (Use Database; Select * from Table)
Try that anywhere. Broken. You might get it to work like this, as #AlwaysLearning suggested:
Select * from openquery ([Linked],
'Exec (''Use Database; Select * from Table'')')
...but that's kind of, like, really gross, compared to the solution at the top. Unless you absolutely need to select from openquery for some reason.

Passing xml to stored procedure on linked server

I've tried something like this:
declare #xml as xml
SET #xml =
(
SELECT DISTINCT
123 AS IdUser
FROM
(
SELECT
1 AS a
) AS ic FOR
XML AUTO
);
exec [linked_server_name].[mydb].[dbo].[stored_procedure] #xml=#xml
Got Msg 9514, Level 16, State 1, Line 5
Tried converting input parameter to varchar(max) and converting it back inside linked server
Still got Msg 9514, Level 16, State 1, Line 5.
Tried executing via openquery - still got Msg 9514, Level 16, State 1, Line 5
Overall, you were on the right path to a solution. If your database is SQL Server, passing XML via linked servers is not supported. Casting it to NVARCHAR(MAX) is a recommended workaround. Along the following:
SQL
DECLARE #xml AS XML =
CAST('' AS XML).query('
element ic {
attribute IdUser {"123"}
}
');
DECLARE #par NVARCHAR(MAX) = CAST(#xml AS NVARCHAR(MAX));
exec [linked_server_name].[mydb].[dbo].[stored_procedure] #xml=#par;

(Select * from table) from another pc without linked server

I am trying to find if there is any way, selecting table from another pc, 'without' creating a linked server.
I found an example which i setting up my sql connection string inside my query, but it gives me error that i need to create a linked server.
SELECT * FROM OPENDATASOURCE (
'SQLNCLI'
,'Data Source=192.168.0.3,1433;Initial Catalog=wiorder;User ID=admin;Password=1234').inventorymaster
Solved by Dan.
When i am trying to insert from destination pc to local pc i am getting error:
Msg 8114, Level 16, State 5, Line 4
Msg 8101, Level 16, State 1, Line 3
An explicit value for the identity column in table 'InventoryMaster' can only be specified when a column list is used and IDENTITY_INSERT is ON.
Here is my query
SET IDENTITY_INSERT InventoryMaster ON
insert into InventoryMaster
SELECT * FROM OPENDATASOURCE (
'SQLNCLI'
,'Data Source=192.168.0.3,1433;Initial Catalog=WiOrder;User ID=admin;Password=1234').WiOrder.dbo.inventorymaster
SET IDENTITY_INSERT InventoryMaster OFF

How do I select from a linked temp table, into a local temp table?

I'm currently calling a stored procedure on a linked server. This stored procedure selects data into a temporary table on this linked server. I'm then attempting to select this data into a temporary table on the local server, so that I can manipulate the data and pull it into various tables.
If I manually run the stored procedure on the server, I'm able to run the second part of the query (--SELECT DATA FROM TEMP TABLE). However, although I'm able to successfully call the stored procedure via the first part of my query, when it gets to the second part, I get the below errors:
Msg 8180, Level 16, State 1, Line 66
Statement(s) could not be prepared.
Msg 208, Level 16, State 1, Line 66
Invalid object name '##Sales'.
Is there another method I could use here? SSIS isn't an option right now, the requirement is to code this via T-SQL.
--CALL STORED PROC FOR SALES DATA
DECLARE #RunSalesStoredProcSQL VARCHAR(1000);
SET #RunSalesStoredProcSQL = 'EXEC [SERVER\INSTANCE].[DATABASE].[dbo].[Extract_Sales_Data]';
EXEC (RunSalesStoredProcSQL) AT [SERVER\INSTANCE];
Print ‘Sales Procedure Executed';
--SELECT DATA FROM TEMP TABLE
SELECT *
INTO ##TempTable
FROM OPENQUERY([SERVER\INSTANCE], 'SELECT * FROM dbo.##Sales');
Print 'Data Selected';
You could return the data from linked server procedure as a simple select, not selecting it in a temp table, and then you can do the following on the local server:
INSERT INTO ##TempTable(ColNames)
EXECUTE [SERVER\INSTANCE].[DATABASE].[dbo].[Extract_Sales_Data]
--select data
SELECT * FROM ##TempTable

Linked Server Query works, but OPENQUERY of same produces error "Could not find server 'SERVER' in sys.servers

Looking for pointers on how to resolve this issue.
I have a linked server setup.
This query works in SSMS, I get rows back.
SELECT tbl.[Col1]
,tbl.[CoL2]
FROM [LINKEDSERVER].[CATALOG].[SCHEMA].[TABLENAME] tbl
But trying to do the same in SSMS with OPENQUERY fails
SELECT [Col1]
FROM OPENQUERY([LINKEDSERVER],
'SELECT tbl.[Col1]
,tbl.[CoL2]
FROM [LINKEDSERVER].[CATALOG].[SCHEMA].[TABLENAME] tbl'
) As Whatever
The messages are as follows:
OLE DB provider "SQLNCLI11" for linked server "SERVER" returned
message "Deferred prepare could not be completed.". Msg 8180, Level
16, State 1, Line 1 Statement(s) could not be prepared. Msg 7202,
Level 11, State 2, Line 1 Could not find server 'SERVER' in
sys.servers. Verify that the correct server name was specified. If
necessary, execute the stored procedure sp_addlinkedserver to add the
server to sys.servers.
The server name SERVER does appear when I check select * from sys.servers
OPENQUERY from here against other linked servers is successful.
Because when you use OPENQUERY you send the query you want to run on the remote server. The error is being thrown by the remote server. Take out the linked server name in the query. Something along these lines.
SELECT [Col1]
FROM OPENQUERY([LINKEDSERVER],
'SELECT tbl.[Col1]
,tbl.[CoL2]
FROM [CATALOG].[SCHEMA].[TABLENAME] tbl'
) As Whatever
This sentence its use with another server but , its ok try this:
EXEC SP_SERVEROPTION 'SERVER\INSTANCIA' ,'DATA ACCESS',TRUE
SELECT * FROM OPENQUERY(YOURSERVER,'SELECT * FROM TABLE').
And its done. :)

Resources