Possible to create SQL Server stored procedure connecting to multiple servers? - sql

My question has to do in regards to the ability of being able to create stored procedures that connect to multiple servers. If anyone's not familiar with it, there's a :CONNECT syntax in SQL that will switch where your query's being run from. For example:
:CONNECT SERVERNAME
SELECT *
FROM Table
GO
This would run the query from where the table is stored as opposed to using linked servers (which cause serious performance issues). Does anyone know if it's possible (and how to achieve it) to create stored procedures that switch between servers? I keep getting various error messages when trying to achieve it. Here would be an example:
:CONNECT SERVERNAME
SELECT *
FROM Table
GO
:CONNECT SERVERNAME2
SELECT *
FROM Table
GO
This would connect to two different servers in the same query.
Thanks
UPDATE - 4.26.2018
All,
We've pretty much decided OPENQUERY is our best solution, at least for stored procedures. Unfortunately, we'll be limited by syntax but performance is MUCH better than using linked servers (which is what we're currently using). I appreciate everyone that's chimed in; Your input was invaluable. If you wish to add anything else, please feel free to do so.
Thanks

Using Linked Servers in a 4-part naming convention will work. It can get ugly fast in regards to performance, so be careful. If you do use Linked Servers, I'd recommend against putting multiple servers in the same SQL statement (including the local server you're on). It isn't terribly efficient. It basically breaks up the query into local and remote queries, it then scrubs the data, and combines it locally before finishing. I've seen users execute queries with multiple servers and take down solid servers in the process.
Another option is the OPENQUERY() method. This still uses a Linked Server, but will send the query to the other server, to process the whole thing there and just ship the data back. This is typically faster and more efficient than the prior.
SELECT
opn.Id,
opn.ColumnName,
opn.AnotherColumnName
FROM OPENQUERY([LinkedServerName],
'SELECT
tbl.Id,
tbl.ColumnName,
tbl.AnotherColumnName
FROM DB.Schema.Object AS tbl
WHERE tbl.ColumnName = ''SomeValue'''
) AS opn
This link gives some more good info: Click Here
SSIS is your best bet here. It's fast, good when using data from multiple servers, and not too difficult to learn (the basics anyway).
So, a few options I've listed...
SSIS - Best option
OPENQUERY() - Better option
Linked Servers - "I guess it works" option

Related

connecting to remote oracle database in SQL

I need to do some data migration between two oracle databases that in different servers. I've thought of some ways to do it like writing a jdbc program but i think the best way is to do it in SQL itself. I can also copy the entire table over to the database I am migrating to but these tables are big and doesnt seem like a "elegant" solution.
Is it possible to open a connection to one DB in SQL developer then connect to the other one using SQL and writing update/insert functions on tables as if they were both in the same connection?
I have read some examples on creating linked tables but none seem to be oracle specific or tell me how to open the external connection by supplying it the server hostname/port/SID/user credentials.
thanks for the help!
If you create a Database Link, you can just select a from different database by querying TABLENAME#dblink.
You can create such a link using the CREATE DATABASE LINK statement.
It depends if its a one time thing or a normal process and if you need to do ETL (Extract, Transform and Load) or not, but ill help you out based on what you explained.
From what i can gather from your explanation, what you attempt to accomplish is to copy a couple of tables from one db to another, if they can reach one another then its really simple, you could just create a DBLINK (http://www.dba-oracle.com/t_how_create_database_link.htm) and then do a SELECT AS INSERT from either side using the DBLINK for one of the tables and the local table as the receiver or sender. Its pretty straight forward.
But if its a one time thing i would just move the table with expdp and impdp since that will be a lot faster and a lot less strain on the DB.
If its something you need to maintain and keep updated, why not just add the DBLINK and use that on both sides, this will be dependent on network performance though.
If this is a bit out of you depth or you cant create dblinks due to restrictions, SQL Developer has had a database copy option for a while and you can go as far a copying individual tables, but its very heavy on the system where its being run (http://deepak-sharma.net/2014/01/12/copy-database-objects-between-two-databases-in-oracle-using-sql-developer/).

Performance hit on DB2 transactional database after linking to SQL Server 2005

We have an AS400 mainframe running our DB2 transactional database. We also have a SQL Server setup that gets loaded nightly with data from the AS400. The SQL Server setup is for reporting.
I can link the two database servers, BUT, there's concern about how big a performance hit DB2 might suffer from queries coming from SQL Server.
Basically, the fear is that if we start hitting DB2 with queries from SQL Server we'll bog down the transactional system and screw up orders and shipping.
Thanks in advance for any knowledge that can be shared.
Anyone who has a pat answer for a performance question is wrong :-) The appropriate answer is always 'it depends.' Performance tuning is best done via measure, change one variable, repeat.
DB2 for i shouldn't even notice if someone executes a 1,000 row SELECT statement. Take Benny's suggestion and run one while the IBM i side watch. If they want a hint, use WRKACTJOB and sort on the Int column. That represents the interactive response time. I'd guess that the query will be complete before they have time to notice that it was active.
If that seems unacceptable to the management, then perhaps offer to test it before or after hours, where it can't possibly impact interactive performance.
As an aside, the RPG guys can create Excel spreadsheets on the fly too. Scott Klement published some RPG wrappers over the Java POI/HSSF classes. Also, Giovanni Perrotti at Easy400.net has some examples of providing an Excel spreadsheet from a web page.
I'd mostly agree with Buck, a 1000 row result set is no big deal...
Unless of course the system is looking through billions of rows across hundreds of tables to get the 1000 rows you are interested in.
Assuming a useful index exists, 1000 rows shouldn't be a big deal. If you have IBM i Access for Windows installed, there's a component of System i Navigator called "Run SQL Scripts" that includes "Visual Explain" that provides a visual explanation of the query execution plan. View that you can ensure that an index is being used.
On key thing, make sure the work is being done on the i. When using a standard linked table MS SQL Server will attempt to pull back all the rows then do it's own "where".
select * from MYLINK.MYIBMI.MYLIB.MYTABE where MYKEYFLD = '00335';
Whereas this format sends the statement to the remote server for processing and just gets back the results:
select * from openquery(MYLINK, 'select * from mylib.mytable where MYKEYFLD = ''00335''');
Alternately, you could ask the i guys to build you a stored procedure that you can call to get back the results you are looking for. Personally, that's my preferred method.
Charles

Disable all queries in SQL Server that don't use named parameters?

It seems that one could stop all threat of Sql injection once and for all by simply rejecting all queries that don't use named parameters. Any way to configure Sql server to do that? Or else any way to enforce that at the application level by inspecting each query without writing an entire SQL parser? Thanks.
Remove the grants for a role to be able to SELECT/UPDATE/INSERT/DELETE against the table(s) involved
Grant EXECUTE on the role for stored procedures/functions/etc
Associate the role to database user(s) you want to secure
It won't stop an account that also has the ability to GRANT access, but it will stop the users associated to the role (assuming no other grants on a per user basis) from being able to execute queries outside of the stored procedure/functions/etc that exist.
There are only a couple ways to do this. OMG Ponies has the best answer: don't allow direct sql statements against your database and instead leverage the tools and security sql server can provide.
An alternative way would be to add an additional tier which all queries would have to go through. In short you'd pass all queries (SOA architecture) to a new app which would evaluate the query for passing on to sql server. I've seen exactly one company do this in reaction to sql injection issues their site had.
Of course, this is a horrible way of doing things because SQL injection is only one potential problem.
Beyond SQL Injection, you also have issues of what happens when the site itself is cracked. Once you can write a new page to a web server it becomes trivial to pass any query you want to the associated database server. This would easily bypass any code level thing you could put in place. And it would allow the attacker to just write select * from ... or truncate table ... Heck, an internal person could potentially just directly connect to the sql server using the sites credentials and run any query they wanted.
The point is, if you leverage the security built into sql server to prevent direct table access then you can control through stored procedures the full range of actions availble to anyone attempting to connect to the server.
And how do you want to check for that? Queries sometimes have constant values that would just as easy be added to the query. For instance, I have a database that is prepared to be multi lingual, but not all code is, so my query looks like this:
SELECT NAME FROM SOMETABLE WHERE ID = :ID AND LANGUAGEID = 1
The ID is a parameter, but the language id isn't. Should this query be blocked?
You ask to block queries that don't use named parameters. That can be easily enforced. Just block any query that doesn't specify any parameters. You can do this in your application layer. But it will be hard to block queries like the one above, where one value is a parameter and the other one isn't. You'll need to parse that query to detect it, and it will be hard too.
I don't think sql server has any built in features to do this.

Linked Tables - SQL Server 2008 to SQL Server 2005

I have a database server that currently has two databases, call them [A] and [B].
[A] is the standard database used for my application
[B] is used by another application (that puts considerable load on the server), however, we use a few tables sparingly (that are shared between my application and the primary application that utilizes [B]). Recently the use of [B] has been increasing and it's causing long wait periods and timeouts in my application.
I'm open to alternative ideas, but at the moment the quickest potential solution I've come up with is to get a second database server and move [A] to that. However, I do need access to some of the tables in [B] - ideally with as little code changes as possible.
We were thinking a setup something like:
Current:
DB Server 1 {[A],[B]} (SQL Server 2005)
New Setup
DB Server 1 {[B]} (SQL Server 2005)
DB Server 2 {[A], [B]} (SQL Server 2008)
Where in the new setup, DBServer2.[B] is a linked table (kind of) to DBServer1.[B]
I looked into linked databases, from my understanding (limited) those work as an alias to a database on another server, which is almost what we want, except it adds the extra server qualifier, and it works on the db level. I'd like to do something like this, but ideally without the server qualifier and on a table level.
So for example, [B] has tables Users and Events. The Users table is updated weekly by batch, and we use it often, so we'd like to have a local copy on the new DBServer2. However, Events we use far less often and needs to be real-time between the two servers. In this case, it would be great to have Events as a linked table.
Further, it would be fantastic if we could use the same markup for queries. Today to query one db from the other we'd do something like
select * from b.events join a.dates
We'd like to continue that, except have the database server know that when we touch events it's really located at dbserver1.b.events.
Does that make sense? I confuse myself sometimes.
Thanks for any help
~P
You can use synonyms for linked objects - http://msdn.microsoft.com/en-us/library/ms177544%28SQL.90%29.aspx
This unfortunately only works for single objects, you CANNOT make a synonym for linkedserver.databasename and then reference synDBName.table.
"Alternative Idea" from me since you said you are open...
How about looking into the cause of the slowness? What is the "Load" you are measuring?
How are your disks laid out on the server?
Maybe you could use more memory, another CPU or Some SQL tuning?
Fixing your issues with a software or hardware fix MAY be faster than getting a server and doing all the installs and then working through the integration problems you may run into.

Clone entire database with a SP

I'm trying to find out if this is possible, but so far I haven't found out any good solutions. What I would like to achieve is write a stored procedure that can clone a database but without the stored data. That means all tables, views, constraints, keys and indexes should be included but without any data. Can it be done?
Sure - your stored proc would have to read the system catalog views to find out what objects are in the database, determine their potential dependencies, and then create a single or a collection of SQL scripts which re-create the database, and execute those.
It's possible - not very nice and easy to do. Especially the dependencies between objects might cause more headaches than first meets the eye....
You could also:
use something like SQL Server Management Studio (if you're on SQL Server - you didn't specify) and create the scripts manually, and just re-execute them on a separate server
use a "diff" tool like Redgate SQL Compare to compare two servers and have the second one brought up to date
I've successfully used the Microsoft SQL Server Database Publishing Wizard for this purpose. It's pretty straightforward, no coding needed. Here's a sample call:
sqlpubwiz script -d DatabaseName -S ServerName -schemaonly C:\Projects2\Junk\ DatabaseName.sql
I believe the default is to create both data and schema, but you can use the schemaonly parameter.
Download it here
In SQL Server you can roll through the system tables (sys.tables, sys.columns, etc.) and construct things one at a time. It's going to be very manual and error prone at the beginning, but it should become systematic pretty quickly.
Another way to do it is to write something in .Net using SMO. Check out this link:
http://www.sqlteam.com/article/scripting-database-objects-using-smo-updated