How to determine if database exists on linked server? - sql-server-2005

I know you can do something like:
select count(*) as Qty from sys.databases where name like '%mydatabase%'
but how could you do something like:
select count(*) as Qty from linkedServer.sys.databases where name like '%mydatabases%'
I guess I could put a stored procedure on the linked server and execute the first select, but is there a way to query a linked server for what databases it holds?

Assuming your linked server login has read permissions on the master.sys.databases table, you can use the following:
select * from linkedserver.master.sys.databases
In the past, I've used this very query on SQL Server 2008 R2.

I think its just a matter of your syntax that is stopping you, try using single quotes instead of %% around your database name:
SELECT COUNT(*) as Qty FROM LinkedServer.master.sys.databases where name like 'mydatabase'
The correct formatting for selecting a Linked Server has already been answered here:
SQL Server Linked Server Example Query

Listed below is a link to a cursor that works:
http://jasonbrimhall.info/2012/03/05/are-my-linked-servers-being-used/
The query will need some rework to include all functions and triggers though.

I'm not sure if a remote master DB is always available through a linked server.
I'll be using the following TRY CATCH probe
BEGIN TRY
EXEC ('SELECT TOP 1 1 FROM MyLinkedServer.MyTestDb.INFORMATION_SCHEMA.TABLES')
END TRY
BEGIN CATCH
PRINT 'No MyTestDB on MyLinkedServer'
END CATCH

Related

Run complex update query on remote server using OPENROWSET

Could you please help me with below task. I need to run below query on remote server
UPDATE prod
SET prod.count = ( SELECT SUM(Inv) FROM cost WHERE pID = prod.ID)
WHERE (( SELECT COUNT(id) FROM Cost WHERE pID = prod.ID ) > 0)
I have tried to use OPENROWSET but do not have enough experience working with it and all online examples with OPENROWSET that I saw use only one table. Can you please give me an idea how to modify this query to use OPENROWSET or ideas of any other solutions?
You can use direct linked server or OPENQUERY (linked_server_name ,'your query').
Best way to to this is to create procedure on target instance and use only easy exec on linked server to run procedure.
exec LinkedServer.TargetDB.TargerSc.NewProcedure
Openrowset is used to "open row set" - primary to access remote data, to modify remote data is openquery.

Find out current database name (MSSQL)

If I want to know the server I can use:
##SERVERNAME
Is there an equivalent function for getting database/catalog name.
I know that we can set it in the script with USE statement but what if it wasnt set and I wanted to query within a sproc what db I was using.
db_name() will give you the name of the current database.
This should do it:
SELECT DB_NAME() AS DataBaseName
Per SQL Authority
db_name() will get you the name of database that you using.
you can see the result with:
select db_name()
With the MSSQL queries below, you can check the current database:
SELECT DB_NAME()
GO
master
In addition, if you don't specify a database on sqlcmd, "master" database is used by default.

How to query results from another query?

I am writing a Trans-SQL script against a MSSQL 2005 Server that intends to query file path of each database present. I am able to list out the database present in the system. But how do I run a separate query based on the results?
The following is the output from the list of databases using the command (SELECT name from sys.databases):
name
----
master
tempdb
model
msdb
Now i would like to take this database names (e.g. master, tempdb) and enter into another query namely (exec sp_helpdb <database_name>).
any ideas?
Not answering your question directly, but if you want to run a query for each db, you can use sp_msforeachdb.
sp_msforeachdb 'EXEC sp_helpdb [?]'
Otherwise, you're going to need to use the results to generate your SQL.
You can build a cursor based on that query then loop through the results, stuff them into a SQL variable, and use that variable to exec your sproc. Unfortunately I'm not able to give you a sample right now, but that is the way I would approach it.
In general, the answer to your question would be "use a subquery".
But in this case, you're using a SQL Server stored procedure. So the best approach is to write your own stored procedure to:
1) call sp_helpdb (or select from master..sysdatabases)
2) Iterate through the results
Here's an example:
http://www.mssqltips.com/sqlservertip/1070/simple-script-to-backup-all-sql-server-databases/
If i am understanding correct , you can use derived table here:-
select database.name (your query) from
(SELECT name from sys.databases) database

SQL - How to insert results of Stored_Proc into a new table without specifying columns of new table?

Using SQL Server 2005, I'd like to run a stored procedure and insert all of the results into a new table.
I'd like the new table to have its columns automatically configured based upon the data returned by the stored procedure.
I am familiar with using the SELECT ... INTO syntax:
SELECT * INTO newtable FROM oldtable
Is this possible?
Edit for clarification: I'm hoping to accomplish something like:
Select * INTO newtable FROM exec My_SP
The only way to do this is w/ OPENROWSET against the local server:
SELECT * INTO #temp
FROM OPENROWSET (
'SQLOLEDB'
, 'Server=(local);TRUSTED_CONNECTION=YES;'
, 'SET FMTONLY OFF EXEC database.schema.procname'
) a
But this is kind of a last-ditch-gotta-do-it-damn-the-consequences kind of method. It requires elevated permissions, won't work for all procedures, and is generally inefficient.
More info and some alternatives here: http://www.sommarskog.se/share_data.html
This seems like a horrible design. You're really going to create a new table to store the results of a stored procedure, every time the stored procedure is called? And you really can't create the table in advance because you have absolutely no idea what kind of output the stored procedure has? What if the stored procedure returns multiple resultsets? What if it has side effects?
Okay, well, if that's what you really want to do...
One way to accomplish this is to use your local server as a linked server and utilize OPENQUERY. First you need to make sure your local server is configured for data access:
EXEC sp_serveroption 'local server name', 'DATA ACCESS', true;
Then you can do something like this:
SELECT * INTO dbo.newtable
FROM OPENQUERY('local server name', 'EXEC yourdb.dbo.yourproc;');
PS How are you going to write code that is going to perform SELECT INTO into a new table name every time (because you can only do SELECT INTO once)? Dynamic SQL? What happens if two users run this code at the same time? Does one of them win, and the other one just gets an error message?
A variation of the same is
create table somename
select * from wherever;

How to query the name of the current SQL Server database instance?

It is a bit of a "chicken or egg" kind of query, but can someone dreamup a query that can return the name of the current database instance in which the query executes? Believe me when I say I understand the paradox: why do you need to know the name of the database instance if you're already connected to execute the query? Auditing in a multi-database environment.
I've looked at all the ## globals in Books Online. "SELECT ##servername" comes close, but I want the name of the database instance rather than the server.
SELECT DB_NAME()
Returns the database name.
SELECT
##servername AS 'Server Name' -- The database server's machine name
,##servicename AS 'Instance Name' -- e.g.: MSSQLSERVER
,DB_NAME() AS 'Database Name'
,HOST_NAME() AS 'Host Name' -- The database client's machine name
I'm not sure what you were exactly asking. As you are writing this procedure for an Auditing need I guess you're asking how do you get the current database name when the Stored Procedure exists in another database. e.g.
USE DATABASE1
GO
CREATE PROC spGetContext AS
SELECT DB_NAME()
GO
USE DATABASE2
GO
EXEC DATABASE1..spGetContext
/* RETURNS 'DATABASE1' not 'DATABASE2' */
This is the correct behaviour, but not always what you're looking for. To get round this you need to create the SP in the Master database and mark the procedure as a System Procedure. The method of doing this differs between SQL Server versions but here's the method for SQL Server 2005 (it is possible to do in 2000 with the master.dbo.sp_MS_upd_sysobj_category function).
USE MASTER
/* You must begin function name with sp_ */
CREATE FUNCTION sp_GetContext
AS
SELECT DB_NAME()
GO
EXEC sys.sp_MS_marksystemobject sp_GetContext
USE DATABASE2
/* Note - no need to reference master when calling SP */
EXEC sp_GetContext
/* RETURNS 'DATABASE2' */
Hope this is what you were looking for
You can use DB_NAME() :
SELECT DB_NAME()
SELECT DB_NAME() AS DatabaseName
simply use:
select ##servicename
You should be able to use:
SELECT SERVERPROPERTY ('InstanceName')
You can get the instance name of your current database as shown below:
SELECT ##SERVICENAME -- SQLEXPRESS
SELECT SERVERPROPERTY ('InstanceName') -- SQLEXPRESS