Connecting to two diffrent data bases using Pro* C code - database

how can we connect to two different databases using Pro* C code. I have entries in tnsnames.ora file. By default it is connection to one of the Databases using EXEC SQL CONNECT statement which I am not sure how it is connecting. I want to connect to another DB which is having an entry in tnsnames.ora file. I am using OpenVMS OS.

Vijay Kumar
Below outlines what I have done in the pass to accomplish this.
Default connection
If you do not have a CONNECT statement in your code, Oracle will perform an auto connect when it encounters the first SQL statement. It uses credential information configure by the person who setup the database.
Multiple connections
To connect to multiple databases in Pro C, you must make an explicit connection to all databases reference by the code.
Outline below are the 3 steps I done in the pass to accomplish this:
Declare a database alias name. This will be used to reference the
connection.
Explicitly connect to the database and assigned the alias to the connection. This is done by including an AT clause in the CONNECT statement.
In following SQL statements, reference the connection by including an AT clause.
Example code:
/*
* Declare the database aliases
*/
EXEC SQL DECLARE DB1 DATABASE;
EXEC SQL DECLARE DB2 DATABASE;
/*
* Explicitly connect to the database. Include an AT clause to name the connection
*/
EXEC SQL CONNECT :db1_uid IDENTIFIED BY :db1_pwd
AT DB1;
EXEC SQL CONNECT :db2_uid IDENTIFIED BY :db2_pwd
AT DB2;
/*
* In the SQL statements, reference the connection by including the AT clause.
*/
EXEC SQL AT DB1 SELECT COL1 INTO :var1
FROM TABLE_1
WHERE COL2 = 'some_value';
EXEC SQL AT DB2 SELECT COLUMN1 INTO :var2
FROM TABLE_2
WHERE COLUMN2 = 'some_value';
EXEC SQL AT DB1 COMMIT WORK RELEASE;
EXEC SQL AT DB2 COMMIT WORK RELEASE;
Things to note:
DB1 and DB2 are programmer define alias names.
Passwords, represented by the variables db1_pwd and db2_pwd, must be
variables and not hard coded values.
The username value, stored in variables db1_uid and db1_uid2, was in the following format: username#DatabaseName
Note I believe there are other methods for accomplish this. This is the method I was successful in getting to work.
You can find more information on connecting to databases in the Oracle Pro *C/C++ Programmer’s Guide.

Related

How to automatically execute "create table" statements generated with select statement?

I have to move some data from our remote customer's mssql database to remote db2 database. On mssql server I own I created linked server to customer's source mssql database (I only have read permissions on) and created another linked server to remote db2 server.
I created some complex transformation, but for simplicity of this forum, lets simplify:
select
'create table [remotedb2server].[remotedb2db].[myschema].'
+ name
+ "COLUMS HERE AND SOME COMPLEX TRANSFORMATION"
from [remotemssqlserver].[remotemssql].[sys].[tables]
How to automatically execute above "create table" statements generated from select statement? I need a solution to be able to schedule it regularly in e.g. SQL Agent job.
I also have "drop table" select, "insert into" select etc and I would like to use the same logic.
This is known as dynamic SQL. You can execute arbitrary generated SQL by calling sp_executesql and passing in your command as a parameter. Keep in mind this has the potential to be very dangerous, as it exposes you to sql injection vulnerabilities.

Copy Oracle table to SQL Server

I need to copy data from a linked server Oracle table and append to SQL Server table in a regular time interval.
Without using SSIS or any external etl, can this be done by using open query? I have read in forums that the table has to be exported to csv and then imported back again into SQL Server . Is there an alternative as this will be continuous process ?
Certainly. As long as you've configured the Linked Server properly within SQL Server, and your user account has the right permissions in Oracle, getting and sending data between the two is fairly trivial.
Selecting data from Oracle into SQL Server:
IF OBJECT_ID('tempdb..#myTemp') IS NOT NULL DROP TABLE #myTemp
SELECT *
INTO #myTemp
FROM OPENQUERY(MyLinkedServer, 'SELECT col1, col2
FROM OracleTableName
WHERE SomeColumn = ''Human Resources''')
Inserting data from SQL Server into Oracle:
-- note: please make sure you have your columns in the exact same order!
INSERT INTO OPENQUERY(MyLinkedServer, 'SELECT col1
FROM OracleTableName ')
SELECT myPK
FROM AdventureWorks2014.dbo.SomeTable
And you can even drop or recreate a table in Oracle from SQL Server, and run stored procedures.
To create a linked server, I use the below script and these settings:
-- make sure you have Oracle drivers on your SQL Server, and an up-to-date TNSNames.ora file
EXEC master.dbo.sp_addlinkedserver #server = N'MyLinkedServer', #srvproduct=N'Oracle', #provider=N'OraOLEDB.Oracle', #datasrc=N'TNS_NAME_HERE'
-- disable any logins not explicitly mapped
EXEC master.dbo.sp_droplinkedsrvlogin #rmtsrvname = N'MyLinkedServer', #locallogin = NULL
-- login mapping between SQL Server user and their appropriate Oracle account
EXEC master.dbo.sp_addlinkedsrvlogin #rmtsrvname=N'MyLinkedServer',#useself=N'False',#locallogin=N'domain\username',#rmtuser=N'ORACLE_USERNAME',#rmtpassword='ORACLE_PASSWORD'
-- add a mapping for your SQL Agent account if these will run under jobs,
-- and your SQL Engine account if you still get errors on things that are automated,
-- unless those automated jobs are explicitly running under user accounts
Honestly, the hardest part is making sure you get Oracle drivers installed right on the SQL Server. After that, it's very straightforward.

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)

Update SAS 9.1 Program to Connect to SQL Server DB instead of Access mdb

At my job there's a SAS script that connects to a Microsoft Access database to retrieve data to a flat file. I've been tasked with adapting it to connect to a SQL Server database instead. We have SAS 9.1 and I cannot update the version because that's not my decision. Here's the code that connects to the Access database (I've replaced the server name and folder names with generic tags for this post):
proc import out=SPONSOR
datatable="SPO_LOAD_UNBLIND"
dbms=ACCESS2000 replace;
database="\\<Server>\<Folder>\<Subfolder>\PROCESS.mdb";
memosize=2048;
run;
What do I need to do to connect this to a SQL Server database named "DM_C0000" with the same table name as in the Access database ("SPO_LOAD_UNBLIND")?
This ended up working:
proc sql;
connect to odbc (dsn=<dsn> user=<userid> pwd=<password>);
create table SPONSOR as select * from connection to odbc(select * from <database>.<schema>.<table>);
quit ;
Alternatively, you can connect to all current tables of a SQL Server database with a libname via ODBC.
* WITH DSN;
libname mydata odbc datasrc="DSN Name" user="username" password="password";
* WITH DRIVER (change driver name to your current installation);
libname mydata odbc complete="driver=SQL Server; Server=servername;
user=username; pwd=password; database=databasename;";
Just be aware changes to tables in SAS affects live database tables. Additionally, deleting entire library deletes all tables in database (not database itself). Instead, be sure to unassign libname.

how to transfer data from one server to another dynamically..?

I have many linked servers that contains similar databases, Now i am asked to make a stored procedure to transfer data from database of one sever to another server's database. but I am supposed to give the destination server name, source server name, destination database name, souce database name as parameters to the stored proc.
I am able to do it between different databases of the same server using dynamic sql.
SET #dynsql =N'INSERT INTO '+#destinationDBname+N'..UIElement (UIElementID,UIElementName)
SELECT #LatestUIElementId,UIElementName
FROM '+QUOTENAME(#sourceDBname)+N'.dbo.UIElement WHERE UIElementID = #OldUIElementId'
EXEC sp_executesql #dynsql,N'#LatestUIElementId int',#LatestUIElementId =#LatestUIElementId
but unable to find a way which can be used between servers.
It seems to me that you are missing destination server in your query. From what I see above you only have destination database.
Query for destination server should look like this
select * from [Server].database.schema.table

Resources