SQL Server : double hop linked server running SELECT Query - sql-server

I'm quite new to SQL Server. I have a question: I have 3 SQL servers, 2 on domain Domain1 and 1 on Domain2.
SQL Server 1 & 2 are on Domain1
SQL Server_3 is on Domain2.
SQL Server_1 - linked to SQL Server_2 and SQL Server 2 is linked to SQL Server 3.
My Windows authentication is Admin on all Windows servers and SQL Servers across all 3 servers. I'm trying to run a SELECT query on SQLServer_1 to retrieve data from SQLServer_3 using SQLServer_2 as a middle jump point (connecting directly between SQLServer_1 and SQLServer_3 unfortunately is out of options)
I've tried running these query on SQLServer_1 :
SELECT *
FROM [SQLServer_2].[SQLServer_3].[DBName_1].[Table_Name1]
But I get this error:
The object name 'SQLServer_2.SQLServer_3.DBName_1.Table_Name1' contains more than the maximum number of prefixes. The maximum is 3.
SELECT *
FROM [SQLServer_3].[DBName_1].[Table_Name1]
results in:
Could not find server 'SQLServer_3' 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.
So both didn't work.
Please HELP. Is it even possible?

Thank you ZLK 23. He's suggestion worked. I dont know how to post it
as an answer if any one does please help me out.
Perhaps use OPENQUERY on the second server to run a query on the third? e.g. on server 1 select * from openquery(server2, 'select * from server3.database.schema.table;'); Alternatively, you might consider executing a stored procedure on server2 (that connects to server3) from server1. – ZLK 23 hours ago
I ran this query from SQLServer_1. In my understanding it runs query
SELECT on SQLServer_2 the SELECT QUERY in the second parameter and
retrieves the results back. Which has worked perfect for me.
SELECT * FROM OPENQUERY(SQLSERVER_2,'SELECT * FROM 'SQLSERVER_3.DBNAME.TABLENAME')
Thank you again.

Related

DB Link from Oracle to MS Server

I am new to this forum and already searched for 45 minutes to find a solution for my problem. I hope you can help me.
A Gateway to a remote Microsoft SQL Database was installed on a Oracle Server (Oracle 12c). The tsnnames.ora file was appropiately set up.
For the connection, I created a database link (In the Oracle DB) as follows:
CREATE DATABASE LINK TEL CONNECT TO "fb_B2C" IDENTIFIED BY "passwort" USING 'dg1msql';
When I now execute the Select statement:
SELECT "name" FROM "sys"."databases"#TEL
it shows me the according databases. Among others, I can see the AB_Colors database.
Now, I want to select a view in the AB_Colors database.
Due to the fact I can connect to this database via Excel, I know that in the database AB_Colors, there are 10 Views(A,B,C,..). I would like to select the View C from the database AB_Colors via the DB LInk.
Owner of the View is b2b.
How do i need to formulate the select statement to do it?
I already tried different writings:
SELECT * FROM b2b.C#TEL;
SELECT * FROM "AB_colors"."b2b"."C"#TEL;
SELECT * FROM [AB_Colors].[b2b].[C]#TEL;
The common error message is: View/Table does not exist
I highly appreciate your help,
Fedja
This is the correct format
SELECT * FROM "b2b"."C"#TEL;
The issue maybe because the database you want to select from is not the one specified in the gateway for dg1msql. You can't add the database name to the query so you must specify it in the gateway connection.
This is defined in
$ORACLE_HOME/dg4msql/admin/initdg4msql.ora
where you should check HS_FDS_CONNECT_INFO

How can I join two tables from two different connections or instances in SQL Server? [duplicate]

How can I select data in the same query from two different databases that are on two different servers in SQL Server?
What you are looking for are Linked Servers. You can get to them in SSMS from the following location in the tree of the Object Explorer:
Server Objects-->Linked Servers
or you can use sp_addlinkedserver.
You only have to set up one. Once you have that, you can call a table on the other server like so:
select
*
from
LocalTable,
[OtherServerName].[OtherDB].[dbo].[OtherTable]
Note that the owner isn't always dbo, so make sure to replace it with whatever schema you use.
You can do it using Linked Server.
Typically linked servers are configured to enable the Database Engine to execute a Transact-SQL statement that includes tables in another instance of SQL Server, or another database product such as Oracle. Many types OLE DB data sources can be configured as linked servers, including Microsoft Access and Excel.
Linked servers offer the following advantages:
The ability to access data from outside of SQL Server.
The ability to issue distributed queries, updates, commands, and transactions on heterogeneous data sources across the enterprise.
The ability to address diverse data sources similarly.
Read more about Linked Servers.
Follow these steps to create a Linked Server:
Server Objects -> Linked Servers -> New Linked Server
Provide Remote Server Name.
Select Remote Server Type (SQL Server or Other).
Select Security -> Be made using this security context and provide login and password of remote server.
Click OK and you are done !!
Here is a simple tutorial for creating a linked server.
OR
You can add linked server using query.
Syntax:
sp_addlinkedserver [ #server= ] 'server' [ , [ #srvproduct= ] 'product_name' ]
[ , [ #provider= ] 'provider_name' ]
[ , [ #datasrc= ] 'data_source' ]
[ , [ #location= ] 'location' ]
[ , [ #provstr= ] 'provider_string' ]
[ , [ #catalog= ] 'catalog' ]
Read more about sp_addlinkedserver.
You have to create linked server only once. After creating linked server, we can query it as follows:
select * from LinkedServerName.DatabaseName.OwnerName.TableName
SELECT
*
FROM
[SERVER2NAME].[THEDB].[THEOWNER].[THETABLE]
You can also look at using Linked Servers. Linked servers can be other types of data sources too such as DB2 platforms. This is one method for trying to access DB2 from a SQL Server TSQL or Sproc call...
Querying across 2 different databases is a distributed query. Here is a list of some techniques plus the pros and cons:
Linked servers: Provide access to a wider variety of data sources than SQL Server replication provides
Linked servers: Connect with data sources that replication does not support or which require ad hoc access
Linked servers: Perform better than OPENDATASOURCE or OPENROWSET
OPENDATASOURCE and OPENROWSET functions:
Convenient for retrieving data from data sources on an ad hoc basis.
OPENROWSET has BULK facilities as well that may/may not require a format file which might be fiddley
OPENQUERY: Doesn't support variables
All are T-SQL solutions. Relatively easy to implement and set up
All are dependent on connection between source and destionation which might affect performance and scalability
These are all fine answers, but this one is missing and it has it's own powerful uses. Possibly it doesn't fit what the OP wanted, but the question was vague and I feel others may find their way here. Basically you can use 1 window to simultaneously run a query against multiple servers, here's how:
In SSMS open Registered Servers and create a New Server Group under Local Server Groups.
Under this group create New Server Registration for each server you wish to query. If the DB names are different ensure to set a default for each in the properties.
Now go back to the Group you created in the first step, right click and select New Query. A new query window will open and any query you run will be executed on each server in the group. The results are presented in a single data set with an extra column name indicating which server the record came from. If you use the status bar you will note the server name is replaced with multiple.
try this:
SELECT * FROM OPENROWSET('SQLNCLI', 'Server=YOUR SERVER;Trusted_Connection=yes;','SELECT * FROM Table1') AS a
UNION
SELECT * FROM OPENROWSET('SQLNCLI', 'Server=ANOTHER SERVER;Trusted_Connection=yes;','SELECT * FROM Table1') AS a
I had the same issue to connect an SQL_server 2008 to an SQL_server 2016 hosted in a remote server. Other answers didn't worked for me straightforward. I write my tweaked solution here as I think it may be useful for someone else.
An extended answer for remote IP db connections:
Step 1: link servers
EXEC sp_addlinkedserver #server='SRV_NAME',
#srvproduct=N'',
#provider=N'SQLNCLI',
#datasrc=N'aaa.bbb.ccc.ddd';
EXEC sp_addlinkedsrvlogin 'SRV_NAME', 'false', NULL, 'your_remote_db_login_user', 'your_remote_db_login_password'
...where SRV_NAME is an invented name. We will use it to refer to the remote server from our queries. aaa.bbb.ccc.ddd is the ip address of the remote server hosting your SQLserver DB.
Step 2: Run your queries
For instance:
SELECT * FROM [SRV_NAME].your_remote_db_name.dbo.your_table
...and that's it!
Syntax details: sp_addlinkedserver and sp_addlinkedsrvlogin
Server 2008:
When in SSMS connected to server1.DB1 and try:
SELECT * FROM
[server2].[DB2].[dbo].[table1]
as others noted, if it doesn't work it's because the server isn't linked.
I get the error:
Could not find server DB2 in sys.servers. Verify that the correct
server name was specified. If necessary, execute stored procedure
sp_addlinkedserver to add the server to sys.servers.
To add the server:
reference: To add server using sp_addlinkedserver
Link: [1]: To add server using sp_addlinkedserver
To see what is in your sys.servers just query it:
SELECT * FROM [sys].[servers]
Simplified solution for adding linked servers
First server
EXEC sp_addlinkedserver #server='ip,port\instancename'
Second Login
EXEC sp_addlinkedsrvlogin 'ip,port\instancename', 'false', NULL, 'remote_db_loginname', 'remote_db_pass'
Execute queries from linked to local db
INSERT INTO Tbl (Col1, Col2, Col3)
SELECT Col1, Col2, Col3
FROM [ip,port\instancename].[linkedDBName].[linkedTblSchema].[linkedTblName]
Created a Linked Server definition in one server to the other (you need SA to do this), then just reference them with 4-part naming (see BOL).
select *
from [ServerName(IP)].[DatabaseName].[dbo].[TableName]
As #Super9 told about OPENDATASOURCE using SQL Server Authentication with data provider
SQLOLEDB
. I am just posting here a code snippet for one table is in the current sever database where the code is running and another in other server '192.166.41.123'
SELECT top 2 * from dbo.tblHamdoonSoft tbl1 inner JOIN
OpenDataSource('SQLOLEDB','Data Source=192.166.41.123;User ID=sa;Password=hamdoonsoft')
.[TestDatabase].[dbo].[tblHamdoonSoft1] tbl2 on tbl1.id = tbl2.id
I know this is an old question but I use synonyms. Supposedly the query is executed within database server A, and looks for a table in a database server B that does not exist on server A. Add then a synonym on A database that calls your table from server B. Your query doesn't have to include any schemas, or different database names, just call the table name per usual and it will work.
There's no need to link servers as synonyms per say are sort of linking.
sp_addlinkedserver('servername')
so its should go like this -
select * from table1
unionall
select * from [server1].[database].[dbo].[table1]
Server Objects---> linked server ---> new linked server
In linked server write server name or IP address for other server and choose SQL Server
In Security select (be made using this security context )
Write login and password for other server
Now connected then use
Select * from [server name or ip addresses ].databasename.dbo.tblname
I hope the clarifications all mentioned above, have answered the OP's original question. I just want to add a code snippet for adding SQL Server as a linked server.
At most basic, we can simply add SQL Server as a linked server by executing sp_addlinkedserver with only one parameter #server, i.e.
-- using IP address
exec sp_addlinkedserver #server='192.168.1.11'
-- PC domain name
exec sp_addlinkedserver #server='DESKTOP-P5V8JTN'
SQL Server will automatically fill SRV_PROVIDERNAME, SRV_PRODUCT, SRV_DATASOURCE etc. with default values.
By doing this, we've to write the IP or PC domain name in the 4 part table address in the query (example below). This can be more annoying or less readable when the linked server will not have a default port or instance, the address will look similar to this 192.168.1.11,1430 or 192.168.1.11,1430\MSSQLSERVER2019.
So, to keep 4 part address short and readable, we can add an alias name for the server instead of the full address by specifying other parameters as follows-
exec sp_addlinkedserver
#server='ReadSrv1',
#srvproduct='SQL Server',
#provider='SQLNCLI',
#datasrc='192.168.1.11,1430\MSSQLSERVER2019'
But when you'll execute the query, the following error will show- You cannot specify a provider or any properties for product 'SQL Server'.
If we keep the server product property value empty '' or any other value, the query will execute successfully.
Next step, make login to the remote linked server by executing the following query-
EXEC sp_addlinkedsrvlogin #rmtsrvname = 'ReadSrv1', #useself = 'false', #locallogin = NULL, #rmtuser = 'sa', #rmtpassword = 'LinkedServerPasswordForSA'
Finally, use the linked server with 4 part address, the syntax is-
[ServerName].[DatabaseName].[Schema].[ObjectName]
Example-
SELECT TOP 100 t.* FROM ReadSrv1.AppDB.dbo.ExceptionLog t
To list existing linked servers execute:
exec sp_linkedservers
To delete a linked server execute:
exec sp_dropserver #server = 'ReadSrv1', #droplogins='droplogins' (delete login as well) OR
exec sp_dropserver #server = 'ReadSrv1', #droplogins='NULL' (keep login)

Access Database - Understand Pass Through

I have been given an Access Database that I have to try to decipher what it is doing.
As a start I see that there is a Pass Through query with a command like:
Exec RefreshGLTableLatestEntries
#sourceDB = 'DB_NAME' ,
#tablePrefix = 'TableName$' ,
#logFile = 'C:\logDB.txt'
When I run it I will get something like:
Result
Success... 108 rows inserted with a total amount of $0.000000
What I don't understand is where are the rows being copied from or copied to.
In the MSSQL database I don't see a table, query, standard procedure or function called 'TableName$'. There are quite a few tables & queries called 'TableName$SomethingElse'. Is there a way to see more details on where is the data coming from?
Similarly, how can I see where are the rows being inserted to? I can not find any file named 'logDB.txt' in my hard disk to see the log. I would suspect that it might not say much more that '...108 rows insterted...'
I'm using:
Access 2016 from Office 365, Version 1609
MS SQL Server Management Studio v17.1
Any ideas on how to get more information on how to get more information on what the Pass Through do?
A Pass-Through query in Access is equivalent to running its SQL code in SQL Server Management Studio.
(In the database that is designated by the connection string of the Pass-Through query.)
The SQL is sent as-is to MSSQL and run there.
RefreshGLTableLatestEntries is the stored procedure that is executed here. You need to locate and analyze it in SQL Server.

Job run in sql sever agent insert all null data.

I have a store procedure which insert data into a table in sql. It work find in SQL however when i create a job in sql server management studio to execute this store procedure by
exec store procedure name
the job does run successfully but all the data insert into the table is null.
i have no idea how this happen, please help. Thanks
Part 1:
We need to know more information than what you are supplying.
Here is a list of things to start.
1 - Generate TSQL for the table.
2 - Send us a couple of records to insert.
3 - Sample TSQL code inside the job step.
4 - What account is SQL Agent running under?
5 - Is the job running in the correct database when executing the TSQL statement?
6 - Are there any errors in the job history.
In short, this task can be easily done.
A screen shot or two would be worth a 1000 words!
Part 2:
Please use the snippet tool in windows to grab a screen shot so that I can see what is wrong.
It is very difficult to diagnose things remotely via just words.
Here are some more things to check.
1 - Are you a local admin of the laptop or server?
2 - Make sure you open the SQL server configuration manager as an admin.
This can be accomplished by right clicking the icon and selecting run as an admin instead of a double click to launch.
Below is a sample image of my configuration manager.
Here is the status of my SQL Server agent and the account it is running under.

SQL Server Management Studio Express not showing recently added data

I recently installed and have been using Microsoft SQL Server Management Studio Express 9.00.4035.00 to manage a remote database on my hosts' SQL Server 2005.
Until now I had been using EMS SQL Manager 2011 Lite and that was working fine.
2 new rows where inserted into one of my tables this morning; one by a customer signing up for a service and the other as a test signup by me.
When I run a typical select query:
[Select top 20 * From tblNotary Order By ID Desc]
I don't see the the 2 most recent rows. But when I run the same query from EMS SQL Manager Lite I see the records.
I also verified when connecting using MS Access 2010 I see the 2 new rows in the table. I have checked and double-checked the connection settings and they match EMS.
Is there a setting or something obvious I am missing? Why can't I see the most recent record insertions? I am on a Windows 7 desktop machine.
The most likely reason is you are connecting to a different database than you expected. You can select ##servername to verify both queries are running against the same server.
If the records are stil being inserted as part of an open transaction and have not been committed, they are called "phantom" rows. You will not see phantom rows if your query runs at transaction isolation level read committed or higher. It may be that EMS SQL Manager Lite is running at read uncommitted, in which case it will include phantom rows in the query.
Sometimes connection strings are a tricky thing. Run this to double check:
select ##servername servername, name, crdate
from sys.sysdatabases
where name = db_name()
if you have an issue running that, just do a simpler version:
select ##servername, db_name(), ##version
Select top 20 * From tblNotary Order By ID Desc

Resources