Matching the schema of a SQL Server DB to an Oracle DB - sql-server

Are there known products that can perform schema matching on any level between SQL Server and Oracle as described here? If not a product, would there be a documented methodology on how to perform maybe some semantic search and comparison of db tables, fields, and even data?
I have an existing SQL Server database which currently experiences a lot of trouble updating its data as it uses a lot of undocumented and unreadable legacy code to extract information from various external data sources. Fortunately, there exists an Oracle database that, based on the nature of the business, seems to contain all the information required by the SQL Server DB. The problem is, the schemas between the two environments are vastly different. They don't follow a common naming convention, and may not even follow the same normalization (some tables may be flat on one and normalized on the other).
The naive approach of trying to go through each table and column in SQL Server and then manually and visually searching for possible matches on the Oracle one seems quite impractical, given that there are hundreds of tables between the two databases.

There are commercial solutions(i.e. Database Compare Suite, Cross Database Studio) in the market which can be used to compare both homogeneous and heterogeneous database environments. But it's not good idea to spent money for those tools only for the schema comparison.
There might be several methods/tools/solutions which has certain limitations based on their scope. I am giving solution to compare schema matching between SQL Server and Oracle. Level of matching like table contents and data structure depends on your level of implementation.
In my Approach, suggesting following steps to full fill your requirements:
Establish SQL Server link server to Oracle Database. Steps are mentioned in the reply trail.
Now, access SQL Server and Oracle tables directly from SQL Server environment itself. It's feasible to compare table data using following approach:
SQL Server :
select field1, field2, field_N from openquery(DEV, 'select * from oracle_owner_schema.testtable')
minus
select field1, field2, field_N from sqlserver_database.schema_name.testtable
3 You can compare data structure(field length, data type, default value, etc.) by using dictionary table from SQL Server and Oracle in a same way.
Establish SQL Server link server to Oracle Database
Setup ODAC
Copy missing DLLs from instaclient to c:\oracle\product...\client_1\BIN [Location in which ODAC was installed.]
Add hostname, portnumber, and service name in c:\oracle\product...\client_1\network\admin\tnsnames.ora, sample:
LOCALSERVER =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = IP_Hostname_Oracle_Server)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)
Configuration in the SQL Server:
a. Connect to SQL server
b. Database>Server Objects>link servers>providers>OraOLEDB.Oracle>Right
c. Click>Properties>"Check Enable for 'Allow Inprocess'", then Save it.
d. Database>Server Objects>link servers>Right Click>New Link Server>
**************General TAB*************************
Linked server: Any Name for link server in MSSQL
Provide name: Oracle Provider
Product Name: Oracle
Datasource: Provide name which you have added in tnsnames.ora
****************Security TAB***************************
Choose "Be made using this security contest:"
Remote login: username for remote database <<e.g. guest >>
With password: password <<e.g. guest>>
How to use:
select * from openquery(Linked_server_Name, 'select * from schema_name.table_name');
i.e. select * from openquery(Any Name_for_link_server_in_MSSQL, 'select * from oracle_owner_schema.testtable');
Note: Version of ODAC and oracle client should be same.

Related

Linked servers (MySQL in SQL Server) brings tables without columns

I have an instance running SQL Server 2014 Express Edition (64-bit Build 19044). I have the same machine running a MySQL server (innodb_version: 5.7.33, protocol version: 10, version_compile_machine: x86_64, version_compile_os: Win64), and I need to write some information in this MySQL Server through a SQL Server script (I need to connect multiple servers and I would like to center everything in this SQL Server. This MySQL server I'm talking about is one of them).
I've found many tutorials teaching to use linked servers, like the following: https://gunnarpeipman.com/mssql-mysql-linked-server/
I've configured the ODBC connection as a System DSN using both MySQL ODBC 8.0 Unicode Driver and ANSI Driver;
I could connect to the MySQL server, and list the tables in this server through SSMS's object explorer. Unfortunately, I spent A LOT of time trying to query data from this server, since I always get errors pointing as if I don't have enough permission to see columns from this table:
When trying to [right click table > Script table as > Select to > clipboard]
[DWGLUO].[dw_vtiger]..[dleads] contains no columns that can be selected or the current user does not have permissions on that object.
When trying to query some data with OPENQUERY:
SELECT * FROM OPENQUERY(DWGLUO_ANSI,'SELECT idlead FROM DWGLUO_ANSI.dw_vtiger..dleads')
Msg 7321, Level 16, State 2, Line 1
An error occurred while preparing the query "SELECT idlead FROM DWGLUO_ANSI.dw_vtiger..dleads" for execution against OLE DB provider "MSDASQL" for linked server "DWGLUO_ANSI".
I can see all tables, but i can't see any columns :(
Also, by running the query below, I managed to find the column names, so they're there somewhere:
EXEC ('SELECT TABLE_SCHEMA,
TABLE_NAME,
COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ''dleads''') AT DWGLUO_ANSI ;
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
dw_vtiger
dleads
idlead
dw_vtiger
dleads
nome
... (continues) ...
If someone could help me I would really appreciate it. Thank you all in advance.

OpenQuery Update against MariaDB returning 'Table doesn't exist'

I have SQL Server 2008 SP4 instance accessing a linked server that is running a MediaWiki database on MariaDB (v 5.5.44). I am able to select from the table no problem:
SELECT *
FROM OPENQUERY(MEDIAWIKI,
'SELECT * FROM wiki.page WHERE page_title = ''Test''')
But when I try to update the table:
UPDATE OPENQUERY(MEDIAWIKI,
'SELECT * FROM wiki.page WHERE page_title = ''Test''')
SET page_title = 'TestChange'
I get the following error message:
OLE DB provider "MSDASQL" for linked server "MEDIAWIKI" returned message "Table 'def.page' doesn't exist".
Msg 7343, Level 16, State 4, Line 1
The OLE DB provider "MSDASQL" for linked server "MEDIAWIKI" could not UPDATE table "[MSDASQL]".
The user has full permissions, so that shouldn't be an issue. I'm also able to make updates against other linked servers running MySQL. Any help is hugely appreciated. Thanks!
EDIT: I am able to get around this by building a dynamic query string and executing it at the linked server, mostly just curious as to why this is happening at this point.
I second Vladislav here. 'def' is used as catalog value(if you look in columns metadata returned by server, or in INFORMATION_SCHEMA tables 'TABLES' or 'COLUMNS'. Both MySQL and MariaDB connectors return table's schema as catalog, and NULL as schema.
It must be that MariaDB Connector/ODBC has but and returns 'def' somewhere in metadata as schema(or catalog?). What version do you use? In fact it could be fixed in latest version. But please better proceed in the JIRA issue created by Vladislav
What kind of ODBC driver do you use? There are 2, MariaDB one, and MySQL one. This looks like a bug in one of these ODBC. Now what does "def" mean. There is a great amount of confusion in MySQL world about catalog, database and schema. MySQL result sets are returned with metadata (column info description). Column info contains several fields, among them "table catalog" (always hardcoded "def") , and also "table schema", aka database. Catalog does not have any meaning currently, and never had, but who knows maybe it could mean something in the future. "schema" on the other hand, is something that you can put into UPDATE command ( UPDATE schema.table SET field=value WHERE ...) . So the bugs seems to be is that one of the ODBC drivers incorrectly chooses "catalog" over "schema".

origin of a linked server

I used this query to determine what databases are using the 5 linked servers on a SQL server.
However, the results don't make sense to me. It is telling me that a server "DOMAIN" is being used by many databases for views, but when I look at the design of the view, I do not see [DOMAIN] in the SQL statement.
Example:
The query result shows me that the database [StrongMailTracking] depends on the linked servers [DOMAIN] and [SDMASQLSRV05.WISPUBS.UCG.COM] for the view [vw_SCP].
When I look at the design of [vw_SCP] I see:
SELECT DISTINCT ucontactid, vemail, vfirstname, vlastname, domain, vcompanymapped, vcompanyname
FROM SDMASQLSRV05.WISPUBS.UCG.COM.MarketingPromotions.dbo.selected_contacts_prelim AS a
When I go Linked Servers and expand DOMAIN, there aren't any tables or views. When I try to expand the System tables and views, I get an error:
Named Pipes Provider: Could not open a connection to SQL Server...
(Microsoft SQL Server, Error: 53)
Any thoughts on what's going on here?

Connect to IBM i server from Sql Server 2008 R2

I have a big deal: I have to connect (I just want to read data, not to write) to my customer's IBM AS/400 (aka iSeries, now IBM i) server...
I think I have all parameters needed (given me by the AS/400 programmer), but I can't figure out which driver I have to use, and if I have all software needed to to this!
I've installed IBM AS/400 ClientAccess 5.8 driver (with a patch for latest OS), and now I'm trying to configure a new Linked Server in my Sql Server 2008 R2 (x64) server.
First problem: Which driver should I use?
I have so many choices (but maybe none of these works!!):
IBM DB2 UDB for iSeries IBMDASQL OLE DB Provider
IBM DB2 UDB for iSeries IBMDA400 OLE DB Provider
IBM DB2 UDB for iSeries IBMDARLA OLE DB Provider
...or maybe other generic OLEDB/ODBC drivers?!
Second problem: Where should I put my parameters (in which fields I mean!)
In any case, in I choose a provider for my Linked Server, obviously I have to set my parameters...but I only have this:
Username of an ADMIN user
Password of the ADMIN user
AS/400 server IP address
The name of "main" archive, in which my data are stored (something like ACG_DATV2)
Third problem: How should I write my queries? How to reference an AS/400 "archive" and tables?
I don't know how to build my reading query: where are tables and views (?!) stored and how can I reference them?
Thank you in advance!
I think there are many ways to achieve what you want, but I'll try to explain what I would do in your case.
With that version of IBM ClientAccess (and also the patch), I should not have troubles in getting connected with a Sql Server 2008 R2 Linked Server if you use the correct data provider.
First of all, try to configure your linked server in this way:
Linked server name: what you want, it's just a custom name (example: MYAS400)
Provider: IBM DB2 UDB for iSeries IBMDASQL OLE DB Provider
Product name: not important, something like iSeries Access OLEDB Driver
Data source: AS/400 server IP address (example: 192.168.0.1)
Either if you configure the Linked Server using the wizard or by SQL code, the first time it will need to access the data of the AS/400 server, you'll be asked for credentials, with a typical iSeries window (look at my example).
Set your username (User ID) and the relative password, without regarding the case of the strings!!
As a general tip (but this is only related to my experience!), try to avoid special characters and upper/lower cases distinctions...
If you arrive here (no problems in the Linked Server creation), the Linked Server should work (so the first and the second problem are solved): let's build the first query!
Once the Linked Server is created, all you need is just to correctly reference the archive, the library and, of course, the correct table and the Linked Server (by name): with this informations, build a query like this (it's the usual T-SQL syntax):
SELECT
(Field1)
, (Field2)
, *
FROM (Linked Server Name).(Catalog Name).(Library).(TableName)
The only information you're probably missing is the "archive": you can easily find it browsing the Catalogs tree inside your new Linked Server, or just use iSeries Access Navigator tool!
So, in your case, I think the query should be (more or less):
SELECT
FILIO
, DTVLD
, DTVLA
, SEQZA
, CFIMP
, PADRE
, TPVLD
, CMVLD
, *
FROM MYAS400.S242DA0A.ACG_DATV2.ANLE200F
Note that S242DA0A is valid only in my case...
Remember also that:
AS/400 will probably ask you for credentials very often: also if you close and reopen SSMS.
Performance?...better to talk of something else :) ... extract the tables in your Sql Server tables and query them from there! Do it with a simple: SELECT (Fields) INTO myTable FROM (AS/400 table)
I've tried this process many times, I didn't have many troubles (once I get skilled about!)...but only for reading data (as you asked)! Never tried to update data!!!
GOOD LUCK!

From SQL Server how do I read from an MS Access database to UPDATE data in one or more table columns?

My SQL Server database table has a column that needs to be Updated with data from an MS Access file. How do I query the MS Access data to perform such an update?
Import Wizard seems to only handle Inserting of new data and not UPDATE existing data? Or am I misunderstanding how to use the wizard?
Sounds like you want to run that operation from the SQL Server side ... "pull" the Access data into SQL Server. If so, you can set up the Access file as a linked server within SQL Server. I've not done that, but have read cases where other people have. I copied these steps from How can I link a SQL Server database to MS Access using link tables in MS Access? at SQLServerPedia.
1) Open EM.
2) Goto the Server to which you want to add it as linked server.
3) Then goto security > Linked Servers section from console tree.
4) Right click on the Client area. Then New Linked Server.
5) Give a name and Specify Microsoft Jet 4.0 as Provider string.
6) Provide the location of the MDB file.
7) Click OK.
Alternatively, you could run the operation from the Access side, and push the data to SQL Server. If that could work for you, use Olivier's instructions to set up the ODBC-linked SQL Server table. Or you do it without creating a DSN: Using DSN-Less Connections.
Either way you link the table, the UPDATE statement you run from within Access might then be as simple as:
UPDATE
linked_table AS dest
INNER JOIN local_table AS src
ON dest.pkey_field = src.pkey_field
SET dest.access_data = src.access_data
WHERE
dest.access_data <> src.access_data
OR dest.access_data Is Null;
First set up a ODBC DSN in Windows. Open Control Panel > Administrative Tools > Data Sources (ODBC). Note that on 64 bit Windows, this might open the 64-bit-administrator. However, if you have a 32-bit Access, you need the 32-bit-administrator (%windir%\SysWOW64\odbcad32.exe).
Then you can link the SQL-Server tables to your access db. In the Link Tables dialog, choose "ODBC Databases()" as file type.
You can then query the linked SQL Server tables as if they were access tables.
See Configure Microsoft Access Linked Tables with a SQL Server Database

Resources