Copy data between two server instances - sql

I want something like :
insert into server2.database1.table1 select * from server1.database1.table1
both tables are exactly the same.
how can I Copy data between two server instances?

SQL - Linked Server
If both servers are SQL Server, you can set up Linked servers - I would suggest using an SQL account for security there.
Then you can simply perform
insert into server2.database1.dbo.table1
select * from server1.database1.dbo.table1 where col1 = 'X'
If you run the query in SQL Management studio connected to server1, and current database set to database1, you won't need the prefix
server1.database1.dbo.
Also, the linked server would be configured on server1, to connect to server2 (rather than the other way around).
If you have the correct OLE DB drivers, this method can also work between different types of RDBMS (ie. non-SQL Server ones).
Open Query
Note: Beware not to rely on linked servers too much especially for filtering, and for joins across servers, as they require data to be read in full to the originating RDBMS before any conditions can be applied. Many complications can arise from Linked Servers, so read up before you embark, as even version differences might cause headaches.
I recommend you use the OPENQUERY command for SQL Servers to get around such limitations. Here's an example, but you should find help specific to your needs through further research:
insert into server2.database1.dbo.table1
select * from OPENQUERY(server1, 'select * from database1.dbo.table1 where col1 = ''X''');
The above code is more efficient, filtering the data on the source server (and using available indexes), before pumping the data through, saving bandwidth/time/resources of both the source and destination servers.
(Also note the double quote '', is an escape sequence to produce a single quote.)
SQL - Temporarily on the same server
Would enable (note the underscore):
insert into server2_database1.dbo.table1
select * from database1.dbo.table1
Still within the SQL query domain. If you can temporarily move the database on server2 to server1, then you won't need the linked server. A rename of the database would appear to be required while co-locating on server1. Achieving such co-location could use various methods, I suggest shrinking database files before proceeding with either:
Backup/Restore - Backup on server2, Restore on server1 (with different name) - perform insert as described above, but without the server1 or server2 prefixes. Then reverse - backup on server1, restore on server2/
Detach/Attach - Rename database, Detach on server2, (compress), copy files to server 1, (decompress), attach on server1, perform insert. Then reverse...
In either case, SQL Server version could be a barrier. If server1 is of a lower SQL version, then both backup and detach/attach methods will likely fail. This can be worked around by moving the server1 database to server2, which may or may not be more suitible.
Other Methods
May be suitable, non-SQL/TSQL method failing favorable environmental factors for previously mentioned methods. And if you have the correct access (OLE DB Drivers, etc..), this method can also work between different types of RDBMS (ie. non-SQL Server ones), and data-sources (such as XML, flatfiles, Excel Spreadsheets...)
SSIS Explicitly with Business Development Management Studio - direct datapump or using delimited file intermeditary.
SSIS Implicitly through SQL Management Studio, by right clicking the database1 on server1 > Tasks > Export, then completing the wizard. May work direct to server2, or using a flat-file intermeditary.
.Net Programming with SqlBulkInsert (I believe the SSIS datapump uses such an object), I can go into more detail about this, if it interests you.
Eg. of SQLBulkInsert (psedo-C# code)
SqlConnection c = new SqlConnection("connectionStringForServer1Database1Here");
SqlConnection c2 = new SqlConnection("connectionStringForServer2Database1Here");
c.Open();
SqlCommand cm = new SqlCommand(c);
cm.CommandText = "select * from table1;";
using (SqlDataReader reader = cm.ExecuteReader())
{
using (SqlBulkInsert bc = new SqlBulkInsert(c))
{
c2.Open();
bc.DestinationTable = "table1";
bc.WriteToServer(reader);
}
}
Pretty cool huh? If speed/efficiency is a concern - SqlBulkInsert based approaches (Such as SSIS) are the best.
Update - Modifying the destination table
If you need to update the destination table, I recommend that you:
Write to a staging table on the destination database (a temporary table, or proper table which you truncate before and after process), the latter is preferable. The former may be your only choice if you don't have CREATE TABLE rights. You can perform the transfer using any one of the above options.
Run a MERGE INTO command as per your requirements from the staging table to the destination table. This can Insert, Update and Delete as required very efficiently.
Such a whole process could be enhanced with a sliding window (changes since last checked), only taking recently changed rows in the source an applying to the destination, this complicates the process, so you should at least accomplish the simpler one first. After completing a sliding window version, you could run the full-update one periodically to ensure there are no errors in the sliding window.

To copy data between two different servers you have several options:
Use linked servers.
Use the data import export wizard.
Use a third party tool such as Red Gate SQL Data Compare.

Similar to Todd C# SqlBulkCopy
Generally this is easier than creating linked servers.
Create a unit test and run the below, if you have triggers then be careful and you will need ALTER permissions.
[Test]
public void BulkCopy()
{
var fromConnectionString = #"fromConnectionString";
var destinationConnectionString = #"destConnectionString2";
using (var testConnection = new SqlConnection(fromConnectionString))
{
testConnection.Open();
var command = new SqlCommand("select * from MyTable;", testConnection);
using (var reader = command.ExecuteReader())
{
using (var destinationConnection = new SqlConnection(destinationConnectionString))
{
using (var bc = new SqlBulkCopy(destinationConnection))
{
destinationConnection.Open();
bc.DestinationTableName = "dbo.MyTable";
bc.WriteToServer(reader);
}
}
}
}
}
}

The best way to do this would be to create a "linked server".
And then you can use below statement into your insert statement in order to define your table
[linkedserver].databasename.dbo.tablename

On Server A add a linked server (B)
http://msdn.microsoft.com/en-us/library/ms188279.aspx
Then you can transfer data between the two.
Export table data from one SQL Server to another
HTH

First You need to add the server
Eg. Server 1 and Server 2
sp_addlinkedserver 'Server-2'
then copy your data from that server to your server by using following query
In Server-1 Write
select * INTO Employee_Master_bkp
FROM [Server-2].[DB_Live].[dbo].[Employee_Master]

If you need an alternative without using Linked Servers, my favorite option is use the command line BCP utility.
With this bulk copy tool, you can export the data to a flat file, copy the file across the network and import it (load it) onto the target server.
https://learn.microsoft.com/en-us/sql/tools/bcp-utility

Related

Create a query that generates an insert statement in SQL Server 2016

I have two tables that I've been working with in our test environment that I need to copy into my SQL Express database so I can continue work on my interface. I would like to use the data that I already have populated in the test environment tables since I don't necessarily want to use production data. I already have the tables created on my local database, all I need to do is insert the data that I already have.
I'm wondering if it's possible to generate an insert query that would contain all of the data that is already in the test environment - something that I can just execute as a query on my local machine.
Is this possible? I can't necessarily work with live production data quite yet, as my interface will be manipulating it.
1. Connect to your TEST server on SQL Server management studio.
2. Expand the Databases node.
3. Right-click your Test Database > Tasks > Generate Scripts:
4. The Introduction page opens. Select Next to open the Chose Objects page. You can select the entire database or specific objects in the database. Select Script specific database objects (select tables table)
5. Select Next to open the Set Scripting Options page. Here you can configure where to save the script and some additional advanced options.
a. Select Save to new query window.
b. Select Advanced and make sure these options are set:
Types of data to script set to Data only.
Step 5.b
Use the SQL Server Import and Export Wizard instead:
https://learn.microsoft.com/en-us/sql/integration-services/import-export-data/start-the-sql-server-import-and-export-wizard?view=sql-server-2017

Linq or SQL join tables on different servers

I have just started working for a new company where I am regularly having to query 8 different servers (all Microsoft SQL 2005 servers). At the moment every morning I am connecting to each server individualy every morning to read the latest entry in a [application].[tmpLogs] table. I have to use different users names and password for each server. I want to write a Linq or SQL query that I can just run in LinqPad to get the last row entered in the tmpLogs table on each server. Does anyone know how I can connect to all the servers and query the tables in one query?
Do the tmpLogs tables have the same columns on each server? If so, you can take advantage of the fact that LINQPad lets you create new typed DataContexts with different connection strings.
Just connect to just one of your databases, and do this:
// Dump the log for the current database:
TmpLogs.OrderByDescending (l => l.Date).First().Dump();
// Dump the logs for other databases:
string[] otherConnectionStrings =
{
"server=...database=....etc",
"server=...database=....etc",
...
}
foreach (string cxString in otherConnectionStrings)
{
var dc = new TypedDataContext (cxString);
dc.TmpLogs.OrderByDescending (l => l.Date).First().Dump();
}
You could choose one SQL Server as your 'master' server. Then set up the other servers as LINKED Servers (see http://msdn.microsoft.com/en-us/library/ms188279.aspx). You could configure a LINQ to SQL object to connect to the LINKED servers via the 'master' server.
You could also just take this out of LINQ and set up scheduled tasks to push the data into a 'warehouse' table periodically. It's easier to communicate with LINKED servers via Stored Procedures than it is via LINQ. As far as I know, LINQ doesn't contain the concept of DB catalogs, only tables. The catalogs are abstracted out in the DataContext object, which if you're using Linqpad, doesn't exist.

Sql: export database using TSQL

I have database connection to database DB1. The only thing I could do - execute any t-sql statements including using stored procedures. I want to export the specific table (or even the specific rows of specific table) to my local database. As you can read abve, DBs are on diffrent servers meaning no direct connection is possible. Therefore question: Is it possible to write query that returns the other query to execute on local server and get data? Also note, that table contains BLOBs. Thanks.
If you have SQL Server Management Studio, you can use the data import function on your local database to get the data. It works as long as you have Read/Select access on the tables you are trying to copy.
If you have Visual Studio you can use the database tools in there to move data between two servers as long as you can connect to both from your workstation.
Needs Ultimate or Premium though:
http://msdn.microsoft.com/en-us/library/dd193261.aspx
RedGate has some usefull tools too:
http://www.red-gate.com/products/sql-development/sql-compare/features
Maybe you should ask at https://dba.stackexchange.com/ instead.
If you can login to the remote db (where you can only issue t-sql), you may create linked server on your local server to the remote and use it later directly in queries, like:
select * from [LinkedServerName].[DatabaseName].[SchemaName].[TableName]

SQL Azure - copy table between databases

I am trying to run following SQL:
INSERT INTO Suppliers ( [SupplierID], [CompanyName])
Select [SupplierID], [CompanyName] From [AlexDB]..Suppliers
and got an error "reference to database and/or server name in is not supported in this version of sql server"
Any idea how to copy data between databases "inside" the server?
I can load data to client and then back to server, but this is very slow.
I know this is old, but I had another manual solution for a one off run.
Using SQL Management Studio R2 SP1 to connect to azure, I right click the source database and select generate scripts.
during the wizard, after I have selected my tables I select that I want to output to a query window, then I click advanced. About half way down the properties window
there is an option for "type of data to script". I select that and change it to "data only", then I finish the wizard.
All I do then is check the script, rearrange the inserts for constraints, and change the using at the top to run it against my target DB.
Then I right click on the target database and select new query, copy the script into it, and run it.
Done, Data migrated.
Since 2015, this can be done by use of elastic database queries also known as cross database queries.
I created and used this template, it copies 1.5 million rows in 20 minutes:
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<password>';
CREATE DATABASE SCOPED CREDENTIAL SQL_Credential
WITH IDENTITY = '<username>',
SECRET = '<password>';
CREATE EXTERNAL DATA SOURCE RemoteReferenceData
WITH
(
TYPE=RDBMS,
LOCATION='<server>.database.windows.net',
DATABASE_NAME='<db>',
CREDENTIAL= SQL_Credential
);
CREATE EXTERNAL TABLE [dbo].[source_table] (
[Id] BIGINT NOT NULL,
...
)
WITH
(
DATA_SOURCE = RemoteReferenceData
)
SELECT *
INTO target_table
FROM source_table
Unfortunately there is no way to do this in a single query.
The easiest way to accomplish it is to use "Data Sync" to copy the tables. The benefit of this is that it will also work between servers, and keep your tables in sync.
http://azure.microsoft.com/en-us/documentation/articles/sql-database-get-started-sql-data-sync/
In practise, I haven't had that great of an experience with "Data Sync" running in production, but its fine for once off jobs.
One issue with "Data Sync" is that it will create a large number of "sync" objects in your database, and deleting the actual "Data Sync" from the Azure portal may or may not clean them up. Follow the directions in this article to clean it all up manually:
https://msgooroo.com/GoorooTHINK/Article/15141/Removing-SQL-Azure-Sync-objects-manually/5215
SQL-Azure does not support USE statement and effectively no cross-db queries. So the above query is bound to fail.
If you want to copy/backup the db to another sql azure db you can use the "Same-server" copying or "Cross-Server" copying in SQL-Azure. Refer this msdn article
You could use a tool like SQL Data Compare from Red Gate Software that can move database contents from one place to another and fully supports SQL Azure. 14-day free trial should let you see if it can do what you need.
Full disclosure: I work for Red Gate Software
An old post, but another option is the Sql Azure Migration wizard
Use the following steps, there is no straight forward way to do so. But by some trick we can.
Step1 : Create another one table with the same structure of Suppliers table inside [AlexDB], Say it as SuppliersBackup
Step2 : Create table with the same structure of Suppliers table inside DesiredDB
Step3 : Enable Data Sync Between AlexDB..Suppliers and DesiredDB..Suppliers
Step4 : Truncate data from AlexDB..Suppliers
Step5 : Copy data from AlexDB..SuppliersBackup to AlexDB..Suppliers
Step6 : Now run the sync
Data Copied to DesiredDB.
If you have onprem version that has the sp_addlinkedsrvlogin, you can setup Linked Servers for both source and target database then you can run your insert into query.
See "SQL Server Support for Linked Server and Distributed Queries against Windows Azure SQL Database" in this blog: https://azure.microsoft.com/en-us/blog/announcing-updates-to-windows-azure-sql-database/
Ok, i think i found answer - no way. have to move data to client, or do some other tricks. Here a link to article with explanations: Limitations of SQL Azure: only one DB per connection
But any other ideas are welcome!
You can easily add a "Linked Server" from SQL Management Studio and then query on the fully qualified table name. No need for flat files or export tables. This method also works for on-prem to azure database and vice versa.
e.g.
select top 1 ColA, ColB from [AZURE01_<hidden>].<hidden>_UAT_RecoveryTestSrc.dbo.FooTable order by 1 desc
select top 1 ColA, ColB from [AZURE01_<hidden>].<hidden>_UAT_RecoveryTestTgt.dbo.FooTable order by 1 desc
A few options (rather workarounds):
Generate script with data
Use data sync in Azure
Use MS Access (import and then export), with many exclusions (like no GUID in Access)
Use 3-rd party tools like Red Gate.
Unfortunately no easy and built-in way to do that so far.
I would recommend SSMS SQL Server Import and Export feature. This feature supports multiple connection configurations and cross-server copy of selected tables. I have tried .NET Sql Server connector, which works very well for the Azure SQL databases.

Duplicate table on 2 different servers (MS SQL 2000/2008)

Ok here is the thing:
I have an old MS SQL 2000 server, and this one will keep running.
however for a new website i have a SQL 2008 server.
I need 3 tables from the old server (lets call it www.oldserver.com) to be on the new server too. the data on the old server still changes daily.
I would like to update the tables immediately when something changes on the old server.
how do you do this. i looked at mirroring but that doesnt seem to be the way to go, now i've checked Import function in SQL Server management studio, but i dont want to import the data all the time. 1 import, then updated like daily are ok. so i guess i need to 'write a query to specify the data to transfer' but i have no idea how that query should look.
the import will go to a SSIS package so it can be scheduled.
what is the best practice here? how should i do it?
You could set up the old server as a Linked Server in the new server.
Then, you could create the tables on the new server not as tables, but as views, directly selecting from the tables on the old server.
Like this (on the new server):
create view OldTableOnNewServer as
select * from OldServer.OldDatabase.dbo.OldTable
Advantages:
no replication/updating necessary -
the data comes directly from the tables on the old server
Disadvantages:
Network traffic: each time someone
selects from the view, the new
server will access the oldserver
over the network
Availability: if the
old server is not available, the
views on the new server won't work at all