SQL Delete using select on linked server issue - sql-server

I have 2 databases with the same tables.
Both databases are on different SQL servers.
I added the second SQL server as a linked server, which works fine.
I want to run a simple DELETE on the linked DB (so that ID's that aren't on the local DB will be deleted).
When I have both DB's on the same server, it works
DELETE FROM TM.dbo.Departments
WHERE NOT EXISTS (SELECT * FROM SPO.dbo.Departments
WHERE TM.dbo.Departments.DepartmentID = spo.dbo.Departments.DepartmentID);
But when I try this on the Linked Server, it looks like this
DELETE FROM [LINKEDSRV].[TM].[dbo].[Departments]
WHERE NOT EXISTS (SELECT * FROM SPO.dbo.Departments WHERE
spo.dbo.Departments.DepartmentID = [LINKEDSRV].[TM].[dbo].[Departments].DepartmentID)
And the last line with is where I can't get it to work.
I hope you guys have a suggestion!

Try this:
DELETE LS
FROM [LINKEDSRV].[TM].[dbo].[Departments] LS
WHERE NOT EXISTS (SELECT 1 FROM SPO.dbo.Departments D
WHERE D.DepartmentID = LS.DepartmentID)
As I mentioned in the comments, 3+ naming for columns is deprecated (i.e. schema.object.column). Alias your objects and then prefix the column name with that for succinct and readable SQL.

Related

How can I get data from 2 different SQL Servers

I have the following situation. I am working with 2 separate SQL servers. Server A hosts the company HR data. There is a view on Server a that provides supervisor info for each employee. I need to get the next supervisor info going up the chain. So I used this to code, I got from the DB admin, to accomplish that
SELECT *
FROM [lawdata].[dbo].[All_Users] ru1
left outer join [lawdata].[dbo].[All_Users] ru2 on ru1.SUPER_EID = ru2.EMP_EID
Now I have data on a separate SQL Server, Server B, that contains some report data the ReportData table contains the employee ID which matches employee ID numbers shown in the view above from Server A. The questions is how can I merge the view from Server A and the Employee ID on Server B so I can link the supervisors to the data rows on Server B.
I have seen this post but just cannot get the syntax right to make it work with my situation
Thanks
You need linked servers. then use
[ServerName].[DatabaseName].[dbo].[tableName]
Create Linked Servers (SQL Server Database Engine)
For this, I'd create an SSIS package to pull down the data from the lawdata server into the database on Server B once a night - probably just a truncate and reload. This way, all of your queries with lawdata data on Server B is localized to one database on one server.
it looks like in your code you did a left outer join on something with itself. Try
SELECT *
FROM [server1].[dbname].[dbo].[tablename] A
left outer join [server2].[dbname].[dbo].[tablename] B on A.columnname = B.columnname
where ["insert where clause here"]
Just in case someone else is trying to solve this same problem here is the solution I came up with; thanks to the suggestion given above
select rd.*, ru1.emp_first, ru1.emp_last, ru1.Super_Last as FirstLineLast,
Super_first as FirstLineFirst,
ru2.Super_Last as SecondLineLast,
2.Super_first as SecondLineFirst
from [TaserEvidence].[dbo].[ReportData] rd left outer join
[soops-lawrept].[lawdata].[dbo].[My_View] ru1 on rd.OwnerBadgeId = ru1.emp_EID
left outer join
[soops-lawrept].[lawdata].[dbo].[rob_users] ru2 on ru1.super_EID = ru2.EMP_EID

Does MSSQL always copy tables when using Linked Server

After googling and looking into the MS documenation (http://msdn.microsoft.com/en-us/library/ms188279.aspx) on linked servers I still couldn't get a clear answer to the following question. I'm thinking about linking 2 SQL Servers so I can create a subset of data from the source DB and insert it into an output DB (with duplicate checks before inserting) but I don't know how MSSQL processes queries that use linked databases.
As far as I know following query will result in LocalServer downloading the FarAwayTable and then executing the query locally (which is killing for performance in my case):
SELECT
f.*
FROM
FarAwayServer.FarAwayDB.dbo.FarAwayTable f,
LocalServer.LocalDb.dbo.LocalTable l
WHERE
f.ID = l.ID
My question is, will MSSQL do the same for the following query or will it only download the result (executing the whole query on the FarAwayServer):
SELECT
*
FROM
FarAwayServer.FarAwayDB.dbo.FarAwayTable f
WHERE
f.ID = 1
It will still act the same (the FarAwayTable table will be downloaded and the query will be executed locally). If you want to execute the query on FarAwayServer you should use OPENQUERY:
SELECT * FROM OPENQUERY([FarAwayServer], 'SELECT * FROM FarAwayDB.dbo.FarAwayTable f WHERE f.ID = 1')

SQL Server Linked Server Example Query

While in Management Studio, I am trying to run a query/do a join between two linked servers.
Is this a correct syntax using linked db servers:
select foo.id
from databaseserver1.db1.table1 foo,
databaseserver2.db1.table1 bar
where foo.name=bar.name
Basically, do you just preface the db server name to the db.table ?
The format should probably be:
<server>.<database>.<schema>.<table>
For example:
DatabaseServer1.db1.dbo.table1
Update: I know this is an old question and the answer I have is correct; however, I think any one else stumbling upon this should know a few things.
Namely, when querying against a linked server in a join situation the ENTIRE table from the linked server will likely be downloaded to the server the query is executing from in order to do the join operation. In the OP's case, both table1 from DB1 and table1 from DB2 will be transferred in their entirety to the server executing the query, presumably named DB3.
If you have large tables, this may result in an operation that takes a long time to execute. After all it is now constrained by network traffic speeds which is orders of magnitude slower than memory or even disk transfer speeds.
If possible, perform a single query against the remote server, without joining to a local table, to pull the data you need into a temp table. Then query off of that.
If that's not possible then you need to look at the various things that would cause SQL server to have to load the entire table locally. For example using GETDATE() or even certain joins. Others performance killers include not giving appropriate rights.
See http://thomaslarock.com/2013/05/top-3-performance-killers-for-linked-server-queries/ for some more info.
SELECT * FROM OPENQUERY([SERVER_NAME], 'SELECT * FROM DATABASE_NAME..TABLENAME')
This may help you.
For those having trouble with these other answers , try OPENQUERY
Example:
SELECT * FROM OPENQUERY([LinkedServer], 'select * from [DBName].[schema].[tablename]')
If you still find issue with <server>.<database>.<schema>.<table>
Enclose server name in []
You need to specify the schema/owner (dbo by default) as part of the reference. Also, it would be preferable to use the newer (ANSI-92) join style.
select foo.id
from databaseserver1.db1.dbo.table1 foo
inner join databaseserver2.db1.dbo.table1 bar
on foo.name = bar.name
select * from [Server].[database].[schema].[tablename]
This is the correct way to call.
Be sure to verify that the servers are linked before executing the query!
To check for linked servers call:
EXEC sys.sp_linkedservers
right click on a table and click script table as select
select name from drsql01.test.dbo.employee
drslq01 is servernmae --linked serer
test is database name
dbo is schema -default schema
employee is table name
I hope it helps to understand, how to execute query for linked server
Usually direct queries should not be used in case of linked server because it heavily use temp database of SQL server. At first step data is retrieved into temp DB then filtering occur. There are many threads about this. It is better to use open OPENQUERY because it passes SQL to the source linked server and then it return filtered results e.g.
SELECT *
FROM OPENQUERY(Linked_Server_Name , 'select * from TableName where ID = 500')
For what it's worth, I found the following syntax to work the best:
SELECT * FROM [LINKED_SERVER]...[TABLE]
I couldn't get the recommendations of others to work, using the database name. Additionally, this data source has no schema.
In sql-server(local) there are two ways to query data from a linked server(remote).
Distributed query (four part notation):
Might not work with all remote servers. If your remote server is MySQL then distributed query will not work.
Filters and joins might not work efficiently. If you have a simple query with WHERE clause, sql-server(local) might first fetch entire table from the remote server and then apply the WHERE clause locally. In case of large tables this is very inefficient since a lot of data will be moved from remote to local. However this is not always the case. If the local server has access to remote server's table statistics then it might be as efficient as using openquery More details
On the positive side T-SQL syntax will work.
SELECT * FROM [SERVER_NAME].[DATABASE_NAME].[SCHEMA_NAME].[TABLE_NAME]
OPENQUERY
This is basically a pass-through. The query is fully processed on the remote server thus will make use of index or any optimization on the remote server. Effectively reducing the amount of data transferred from the remote to local sql-server.
Minor drawback of this approach is that T-SQL syntax will not work if the remote server is anything other than sql-server.
SELECT * FROM OPENQUERY([SERVER_NAME], 'SELECT * FROM DATABASE_NAME.SCHEMA_NAME.TABLENAME')
Overall OPENQUERY seems like a much better option to use in majority of the cases.
I have done to find out the data type in the table at link_server using openquery and the results were successful.
SELECT * FROM OPENQUERY (LINKSERVERNAME, '
SELECT DATA_TYPE, COLUMN_NAME
FROM [DATABASENAME].INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME =''TABLENAME''
')
Its work for me
Following Query is work best.
Try this Query:
SELECT * FROM OPENQUERY([LINKED_SERVER_NAME], 'SELECT * FROM [DATABASE_NAME].[SCHEMA].[TABLE_NAME]')
It Very helps to link MySQL to MS SQL
PostgreSQL:
You must provide a database name in the Data Source DSN.
Run Management Studio as Administrator
You must omit the DBName from the query:
SELECT * FROM OPENQUERY([LinkedServer], 'select * from schema."tablename"')
For MariaDB (and so probably MySQL), attempting to specify the schema using the three-dot syntax did not work, resulting in the error "invalid use of schema or catalog". The following solution worked:
In SSMS, go to Server Objects > Linked Servers > Providers > MSDASQL
Ensure that "Dynamic parameter", "Level zero only", and "Allow inprocess" are all checked
You can then query any schema and table using the following syntax:
SELECT TOP 10 *
FROM LinkedServerName...[SchemaName.TableName]
Source: SELECT * FROM MySQL Linked Server using SQL Server without OpenQuery
Have you tried adding " around the first name?
like:
select foo.id
from "databaseserver1".db1.table1 foo,
"databaseserver2".db1.table1 bar
where foo.name=bar.name

How to do a union across multiple instances of Sql Server?

I have two Sql Servers (two distinct databases, (i.e. two machines)) with the same structure. Is there a way to do a SELECT * FROM (SELECT * FROM TableOnServerA Union SELECT * FROM TableOnServerB)?
Thanks
Yes, just set them up as linked servers and then fully qualify the names in the form of LinkName.DatabaseName.SchemaName(dbo).TableName
SELECT * FROM serverA.database.owner.TableName
Union
SELECT * FROM serverB.database.owner.Tablename
assuming that they are setup as linked server, use books online and go to "linked"
You could create a Linked Server or use OPENROWSET to connect to other SQL database.
You can run a query relating two different machines adding one machine via the sp_addlinkedserver stored procedure. You run it in the database server instance where you will want to execute the query (or on both if you want to execute the query in any server), like this
use master
go
exec sp_addlinkedserver
#server='AnotherServer',
#provider='SQL Server'
The you can run
select * from AnotherServer.database.dbo.table t1
join database.dbo.table t2 on (t1.id = t2.id)
Incidentally if they are on two different servers and you are sure the data is not duplicated use union all, it will be much faster. Also never use select *,specify the field names. Other wise it will break if someone adds a column to A but not to B (or rearranges teh columns in B but not A) I would also add a column indicating which of the two servers the data came from, especially if they might have the same id number but attached to different data (which can happen if you are using autogenerated ids). This can save no end of trouble.

How to make a select query for sql and access databases?

Using SQL server 2000 and Access 2003
Access Database Name - History.mdb
Access Table Name - Events
SQL Database Name - Star.mdf
SQL Table Name - Person
I want to take the field from person table, and include in Events table by using inner join
Tried Query
Select * from Events inner join person where events.id = person.id
So How to make a query for access and sql databases.
I want to make a Select query in access only. Not an sql Database.
Need Query Help?
While you can (possible, should -- why?) use a linked table, there are as ever more than one way to skin a cat. Here's another approach: put the connection details into the query test e.g. something like
SELECT *
FROM [ODBC;Driver={SQL Server};SERVER=MyServer;DATABASE=Star;UID=MyUsername;Pwd=MyPassword;].Person AS P1
INNER JOIN
[MS Access;DATABASE=C:\History;].[Events] AS E1
ON S1.seq = S2.seq
WHERE E1.id = P1.id;
You can set up a linked table in Access to your SQL Server, and the instructions on how to do so vary slightly in Access versions. Look in the help file for "Linked Table", or go here if you have Access 2007.
Once you have a linked table set up, you'll be able to access the SQL Server table in your query. Note that optimizing a linked table join takes some work.
You can create a linked table in Access, that points to the table in SQL. The rest you can achieve in the query designer.
You should add the msaccess db as a remote server.
then you can do that join

Resources