Is it possible to compare tables from different SQL server? - sql-server

I have to compare the tables in Server1 database A dbo.X and Server2, database B dbo.Y. Both table X and table Y contains same values.
SO I need to validate both tables contains same values in every row and column. Is it possible to do it?
Thanks

If you do not want to use any Tool like SSIS/Visual Studio then Linked Server will be required.
Select * FROM Server1.databaseA.dbo.X
EXCEPT
Select * FROM Server2.databaseB.dbo.Y
EXCEPT returns distinct rows from the left input query that aren’t output by the right input query.
EXCEPT

Sure, you can do it by creating linked servers. Please, follow this manual to create it:
Creating Linked Servers
After this you will able to make sql-queries to another server like this:
SELECT name FROM [SRVR002\ACCTG].master.sys.databases ;

There is a more easy way if you have visual studio installed. There is a option to compare schema and data with any server and it is very efficient as you can update the target server within the tool as well.
VisualStudio -> Tools -> SQL server -> Data Comparison

Related

Import multiple Excel files to create 1 table in SQL Server 2012

I have a few experience in using SQL Server 2012.
All I know to import a excel to database is like the following:
open SQL Server Management Studio
right click on the "table" folder -> Tasks -> Import Data
set data source to MS Excel.
It seems that only one Excel is entertained.
But I want to concatenate 6 Excel files (all with same column layouts) to form a single table in SQL Server.
P.S. No need to tell me to concatenate the Excel file manually by copy and paste because each individual Excel file has about ~50,000 records.
Any ideas / solutions by using sql scripts or any other programming methods?
Thanks a lot.
There's a range of ways to do this, but I'll give you the simplest that comes to mind without requiring any deep technical knowledge on your part.
Given that you're using the wizard, firstly on the 'Select Table Sources and Views' page, change the 'Destination' to be the name of the table you've previously created.
Then, under the 'Edit Mappings' menu when selecting your sheets, ensure you have 'Append rows to the destination table' selected, rather than Create/Delete. Within reason, this will achieve your goal.
There is a risk in flat file loading like this that SQL Server will create your table with unsuitable types (i.e. a Column is a text column, but only contained numbers on the first file - so the column was created as an INT and wont accept any other files). You'll need to create the tables from scratch again with the right structure or work with the mappings page to do this work.
Another way for the semi-technical type is as long as the data is equivelent between files, you can simply do your imports into a series of seperate tables:
Table1
Table2
Table3
...
Then do a
INSERT INTO Table1
SELECT * FROM Table2
UNION ALL
SELECT * FROM Table3
... Add tables here
You can then use DROP TABLE to remove the extras.

I need to make sure 2 DB are the same

I'm doing it programmatically (I'm a newbie to sql) I'm getting the data per table within first DB using with being a value from a list of table names that I need to make sure are
there
if there have the corresponding values in the same table in
DB X list all the fields that do not have the same values and the
value in below
Table that does match listing the table, field name, row,
"SELECT * FROM [Dev.Chris21].[dbo].[" & PayrollTablemaskedarray(xxxxxx-2) & "]"
I can copy the whole thing into excel but I'm wondering is there a way to do this using sql?
Thanks
Since you mention that you're doing it programmically I assume you're using visual studio. If so you can take advantage of SQL Server Data Tools (SSDT) to do comparisons of two database schemas or two database data sets. You get this out of the box with VS2012 or VS2013 (and earlier versions too). Might be worth a look...

copy large table from sql server to odbc linked database (postgresql) in ssms

I'm trying to copy created a whole database in SQL Server to Postgres. I've been trying to write a script that can run in ssms with a postgres instance set up as a linked server. This will not be a one off operation.
I've managed to create a script that creates most of the schema i.e. tables, constraints, indexes etc. I do this by using the information_schema tables in sql server and formatting the data to form valid sql for postgres and run EXEC(#sql) AT POSTGRES statement, where POSTGRES is the linked server and #SQL a variable containing my statement. This is working fine.
Now I'm trying to insert the data using a statement like this:
INSERT INTO OPENQUERY(POSTGRES,'SELECT * FROM targettable')
SELECT *
FROM sourcetable
The statements are actually slightly modified in some cases to deal with different data types, but this is the idea. The problem is when the table is particularly large, this statement fails with the error :
Msg 109, Level 20, State 0, Line 0
A transport-level error has occurred when receiving results from the server. (provider: Named Pipes Provider, error: 0 - The pipe has been ended.
I think the error is caused by either postgre or sql server using too much memory generating the large statement. I've found that if I manually select only parts of the data to insert at a time, it works. For instance, the top 10000 rows. But I don't know a way to write a general statement to select only x amount of rows at a time that isn't specific to the table I'm referencing.
Perhaps someone can suggest a better way of doing this though. Keep in mind I do need to change some of the data before inserting it into postgres e.g. geospatial information is transformed to a string so postgres will be able to interpret it.
Thanks!
I have transfered some large databases and for PostgreSQL I see 2 ways:
export data into CSV file, convert CSV file into PostgreSQL COPY format (see https://wiki.postgresql.org/wiki/COPY) and use COPY (wiki page shows more alternatives)
make Jython program that connect to both databases (Python is easy and Jython can work with JDBC drivers), make SELECT from source database (if you have a lot od data then use setFetchSize()), use PreparedStatement with INSERT in destination database and then dest_insert_stmt.setObject(i, src_rs.getObject(i))
I ended up using the OFFSET X ROWS FETCH NEXT Y ROWS ONLY introduced in SQL Server 2012 so the complete statement looked like this:
INSERT INTO OPENQUERY(POSTGRES,'SELECT * FROM targettable')
SELECT *
FROM sourcetable
ORDER BY 1
OFFSET 0 ROWS FETCH NEXT 10000 ROWS ONLY
And everything is working and error appears! I actually iterate through the OFFSET value adding 10,000 to it on every iteration using dynamic SQL.
Not the cleanest or nicest solution. I think most people would be better writing something in another language as mentioned by Michal Niklas, but this worked for me.

How to fetch last added or edited records from SQL Server database?

Currently I'm working on database migration, for this I'm using Pentaho Kettle and Perl scripts.
The migration is from Tumor-registry SQL Server database to CIDER IBM DB2 database.
In this task I want to achieve two objective.
Initial migration: in this I'm migrating all the rows (e.g. 100000) from Tumor-registry (SQL Server) to CIDER (IBM DB2).
Subsequent migration: the Tumor-registry SQL Server database is constantly updating on and off.
It's constantly adding new rows or edits already existing rows.
I have figured out the first step but facing two problems in second step.
a) If Tumor-registry SQL Server database is updated with for example new 10 rows; how can I get those new 10 rows?
b) If already existing 10 rows are updated then how can I get those 10 rows and also want to know which columns are updated.
My Tumor-registry database contain approximately 50 tables.
Any help is greatly appreciated.
Create a new column with TIMESTAMP datatype.This will keep track of the latest edited records in the table.
OR
You can use CHECKSUM function in Sql server.
i think that will provide u a solution by using triger
create triger trigername on tablename
after insert
as
declare #variablename_1 datatype;
select #variablename_1 = column_name from inserted ;
if you want save data in anohter table that last inserted then create an other table
insert into tablename values (#variablename_1);
You could use IBM Change Data Capture, it will take all the DDL and DML in the source database, and replicate them appropiately in the target database.
http://www-01.ibm.com/software/data/infosphere/change-data-capture/
It seems that there are other solutions from other vendors, take a look at: http://en.wikipedia.org/wiki/Change_data_capture

SQL Server spatial and linked servers

I have a SQL Server instance that I've added a linked server to another SQL instance. The table I'm accessing on the linked server contains spatial types. When I try to query the table I receive an error:
Objects exposing columns with CLR types are not allowed in distributed
queries. Please use a pass-through query to access remote object.
If I use OPENQUERY with the same query I get another error:
A severe error occurred on the current command. The results, if any,
should be discarded.
Is there any way to query tables that contain spatial types via linked servers?
One way to work around this is to pass spatial data as NVARCHAR(MAX)
select go=geometry::STGeomFromText(go,0)
from openquery([other\instance],
'select go=convert(nvarchar(max),go) from tempdb.dbo.geom')
note: go is a column name, short for geometry-object
Or using the function instead of explicit cast
select go=geometry::STGeomFromText(go,0)
from openquery([other\instance],
'select go=go.STAsText() from tempdb.dbo.geom')
I came across the same problem, but accepted solution wasn't an option in my case, due to many applications that couldn't be changed to expect a totally different query.
Instead, I think I found a way to cheat the system. On local server run:
CREATE VIEW stage_table
AS
SELECT *
FROM OPENQUERY([REMOTESERVER],'SELECT * FROM [REMOTEDB].[SCHEMA].TARGET_TABLE');
GO
CREATE SYNONYM TARGET_TABLE FOR stage_table;
GO
Voila, you can now simply use
SELECT * FROM TARGET_TABLE;
Which is probably what your applications expect.
Tried the above scenario with local server: SQLEXPRESS 2008 R2, and remote server SQL EXPRESS 2014.
I have another workaround. It doesn't apply to the OP's question since they were trying to select the spatial data. Even if you are not selecting the columns containing spatial data, you'll still get this error. So if you need to query such a table, and do not need to retrieve the spatial data, then you could create a view for the table (selecting only the columns you need, excluding the spatial data columns), then query against that view instead.

Resources