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

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.

Related

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.

Query from SQL Server tables in Oracle using ODI

I have a database in Oracle and a database in SQL Server.
I want to write a query in Oracle and I need to use one of SQL Serever table in it.
Before I used database link but now I must to do this with ODI (Oracle Data Integrator).
The way I used before:
CREATE PUBLIC DATABASE LINK "DBLINK"
CONNECT TO "MatrisApp" IDENTIFIED BY VALUES ':1'
USING 'dg4msql';
INSERT
INTO everyday_deposit_temp ***/*this is a table in oracle*/***
(
"DEP_ID",
"REF_DEPOSIT_TYPE",
"REF_DEPOSIT_SUB_TYPE",
"LEDGER_CODE_SELF"
)
SELECT "DEP_ID",
"REF_DEPOSIT_TYPE",
"REF_DEPOSIT_SUB_TYPE",
"LEDGER_CODE_SELF"
FROM dbo.vw_deposit_changed#dblink
Please help me with this
The most common way to get data from MS SQL Server to Oracle through ODI is to use LKM MSSQL to ORACLE (BCP SQLLDR).
Now if you really want to use a dblink, I would try this approach:
Duplicate a Oracle IKM you want to use
In the definition tab, check the Multi-Connections checkbox and set Microsoft SQL Server for the Source Technology.
In the Options tab, add a new option DBLINK_NAME with Value type.
In the Tasks tab, find the task responsible of the insert and edit the target command to add this after the table name : #<%=odiRef.getOption("DBLINK_NAME")%>
Create a mapping using the new IKM. In the Physical tab, click on the target table and add the dblink name in the Option.

How to copy data from a view of one server into the database table of another server in a SQL server database?

how can i copy data from a view of one server into the database table of another server in a SQL server database without using linked servers method.
I tried using the code:
SELECT [LogEntryID]
,[TimeStamp]
Into [server-2].[database1].[dbo].[table1]
FROM [server-1].[database1].[dbo].[view_1]
I recieve the error " The object name 'server-2.database1.dbo.table1' contains more than the maximum number of prefixes. The maximum is 2.
The copying statement i am using in a groovy code. But for first i am trying it in a query if it works.
You can use opendatasource instead of linked server
insert DestinationTable
select * from opendatasource('SQLOLEDB', 'Server=SourceServer;User Id=Username;Password=Password;').SourceDb.Schema.SourceTable;
OPENDATASOURCE

Query database running on another physical SQL Server

Historically we have a product which installed two databases on the same server. There is an custom application which assumes that both databases are on the same server.
In a new version they have split the databases onto two separate servers and obviously now the custom application is giving the error:
Database 'DB_2' does not exist. Make sure that the
name is entered correctly.
Is there anything I can do in the SQL Server setup so that the application is still able to query the DB_2 database without modifying the custom application?
The query being used is structured as follows:
Use DB_2
SELECT * FROM MyUser.MyTable
You can create a linked Server, then Create a Database DB_2 add a Synonym for different objects. something like below.
use master
GO;
EXEC master.dbo.sp_addlinkedserver #server = N'RemoteServer', #srvproduct=N'SQL Server'
GO
CREATE DATABASE [DB_2];
GO
USE [DB_2]
GO
CREATE SYNONYM [MyUser].[MyTable] FOR [RemoteServer].[db].[MyUser].[MyTable]
GO
You can use Linked Servers feature. In SSMS go to Server Object/Linked Servers folder in Object Explorer. And link second server. So you can query another DB using this SELECT * FROM [Linked_Server_Name].[Database_Name].[Schema_Name].[Table_Name]

SQL Server cross database alias

I'm trying to understand how I can use an alias to reference another database in the same instance, without having to use a hardcoded name.
The scenario is as below:
I have a data db with stores data, an audit db which keeps all changes made. for various reason, i want to keep the audit data in a separate database, not least because it can get quite large and for reporting purposes.
In the data db, I don't want to reference this by a hardcoded name but an alias so that in different environments, I don't have to change the name and various sp's to reference the new name.
for example:
mydevdata
mydevaudit
If a sp exists in mydevdata such as which calls the mydevaudit, I don't want to change the sp when I go to test where the db's may be called mytestdata and mytestaudit. Again, for various reasons, the database names can change, more to do with spaces an instances etc.
So if I had procedure in mydevdata:
proc A
begin
insert into mydevaudit.table.abc(somecol)
select 1
end
when I go to test, I don't want to be change the procedure to reference another name, (assume for sake of argument that happened)
Instead I am looking to do something like:
proc A
begin
insert into AUDITEBALIAS.table.abc(somecol)
select 1
end
I am interested in finding out how I could do something like that, and the pro's and cons.
Also, dymnamic SQL is not an option.
thanks in advance for you help.
You may be able to use synonyms
CREATE SYNONYM WholeTableAliasWithDBetc FOR TheDB.dbo.TheTable
This means all object references in the local DB are local to that DB, except for synonyms that hide the other database from you.
You can also use stored procedures in the audit DB. There is a 3rd form of EXEC that is little used where you can parametrise the stored proc name
DECLARE #module_name_var varchar(100)
SET #module_name_var = 'mydevaudit.dbo.AuditProc'
-- SET #module_name_var = 'whatever.dbo.AuditProc'
EXEC #module_name_var #p1, #p2, ...
Obviously you can change module_name_var to use whatever DB you like
I've just posted this to How to create Sql Synonym or "Alias" for Database Name? which is a workaround for the same situation:
There is a way to simulate this using a linked server. This assumes you have two SQL servers with the same set of databases one for development/test and one live.
Open SQL Server Management Studio on your development/test server
Right click Server Objects > Linked Servers
Select New Linked Server...
Select the General page
Specify alias name in Linked server field - this would normally be the name of your live server
Select SQL Native Client as the provider
Enter sql_server for Product Name
In Data Source specify the name of the development server
Add Security and Server Options to taste
Click OK
The above is for SQL Server 2005 but should be similar for 2008
Once you've done that you can write SQL like this:
SELECT * FROM liveservername.databasename.dbo.tablename
Now when your scripts are run on the development server with the linked server back to itself they will work correctly pulling data from the development server and when the exact same scripts are run on the live server they will work normally.

Resources