How to loop on multiple databases and tables - sql-server

I have a SQL Server instance which contains multiple databases. I have 2 tables which exist in all databases on the server:
Refresh Log
Detailed refresh log.
I want to union all the tables across all databases on the server so the final result will be 2 tables which are the union refresh log and detailed refresh log.
I need help to write the function which runs across all databases.

I'm also a little uncertain as to what you're hoping for, for example if you need the resulting output to be in two permanent tables or if you just need the result when queried. Of course once you build your SELECT you can return it to the caller or put it into a table, so I'll leave that up to you.
If your databases are unchanging, then of course you can just write your query and maybe put it into a VIEW for convenience:
SELECT columns from database1.dbo.RefreshLog
UNION ALL
SELECT columns from database2.dbo.RefreshLog
...
and so on
But if you're saying that your databases are themselves dynamic, in other words that databases may be created or dropped over the lifetime of your project, then you could consider using the "undocumented" procedure sp_msforeachdb to build up a list of databases, and then use THAT list to build your UNION query. Here's a quick script that captures the names of all databases that include a specific table ("Products" in the example):
IF object_id('tempdb..#DatabaseNames') IS NOT NULL
DROP TABLE #DatabaseNames
CREATE TABLE #DatabaseNames (DatabaseName SYSNAME)
execute sp_msforeachdb #command1=
N'IF EXISTS(SELECT * FROM [?].sys.tables WHERE Name = ''Products'')
INSERT #DatabaseNames VALUES(N''Database [?]'')'
SELECT * FROM #DatabaseNames

Related

SQL Server Stored Procedure, View and Table Unique Identifier

Where does SQL Server save its unique identifier for stored procedures, views and tables? When I rename a stored procedure, how does SQL Server know what stored procedure to rename?
I'm hoping it's something like a row number that I can select in a query. By looking at the INFORMATION_SCHEMA, I'm able to get a table of objects but can't figure out how SQL Server keeps track of any changes
I would guess you are talking about object_id. SELECT * FROM sys.objects has all objects and their ID's
You can also do:
select OBJECT_ID('your_proc_name_here')
to see what the object_id is.
As for tracking changes, there is not a table that keeps what your proc was prior to an alter statement or tells you what the view definition was 2 weeks ago. You would have to make a user defined table and write logic to handle that, or use a VCS.

Where did my new table go

I have a database called mbt. I wanted to write some data from temporary table to real table.
--I used this query.
SELECT * INTO new_table FROM #tmp
when i runned the query it returned normal message.
15813 row(s) affected
After that i checked my tables in mbt database, but i couldn't see 'new_table'
how could such a thing be, where the table might have gone.
I may have forgotten to use 'use MBT' statment at the beginning of the query. Does it make problem
I'm using ms sql server 2014(SP2)(KB3171021)-12.0.5000.0(X64)
ANSWER
It gone to Master DB
select 'master' as DatabaseName,
T.name collate database_default as TableName
from master.sys.tables as T
It Will create a new table on your database. but you did not use so it will store in master database on your server.
Run the query below to find databases which have the object new_table:
sp_MSForEachDB 'Use [?] IF EXISTS (SELECT 1 FROM sys.objects WHERE name= ''new_table'')
SELECT DB_NAME()'
I had the same problem. What i did is, I rewrite the statement of use Database and then refresh the database browser after that i got Result. You can try it. may be it will help you.
Always use command "USE db_name" to make sure that you are querying right database.
Below command will show all databases available on the server.
SHOW DATABASES;
If you are using GUI tool to connect DB server, there is a possibility that at the time of connection you got connected to different DB. If you executed the query to create table and inserted record. These records are inserted in new table in different DB than mbt.

Neater way of dynamically selecting a database other than sp_executesql

I am looking to set up a high availability architecture whereby two mirror databases exist (DB1 & DB2) that serve another database with views (DBV) on it. DB1 has the overnight ETL on it, whilst DBV looks at DB2 until the etl is complete on DB1, at which point its views switch to the underlying tables on DB1. Once the ETL is complete on DB1, DB2 is restored with DB1 data before the next day's ETL. The next day, DB1 and DB2 switch roles.
I am looking for a neater/more secure way of switching between the two views than running sp_executesql to run a dynamically built string. I will be looking to also do this on stored procedures from a staging database which need to have their scripts dynamically altered to use the correct database to run the ETL on. Essentially, I am looking to pass the USE statement dynamically and then execute the rest of the script outside of any dynamic statement.
I want to avoid sp_executesql for support reasons for other developers and also to get around any possible extensive concatenation of strings if the stored procedure/view gets particularly lengthy.
Any ideas / different approaches to high availability in this context would be welcome.
One option might be to create a copy of each view in DBV for both target databases - i.e.
some_schema.DB1_myview
some_schema.DB2_myview
and then use a synonym to expose the views under their final names.
CREATE SYNONYM some_schema.myview ON some_schema.DB1_myview
Your switch process would then need only to drop and recreate the synonyms, rather than the views themselves. This would still need to be done with a dynamic SQL statement, but the complexity would be much lower.
A downside would be that there would be a risk of the definitions of the underlying views getting out of sync.
Edit
At the cost of more risk of getting out of sync, it would be possible to avoid dynamic SQL altogether by creating (for instance) a pair of stored procedures each of which generated the synonyms for one database or the other. Your switch code would then only need to work out which procedure to call.
Have you considered renaming the databases as you switch things around? I.e. the following prints 1 followed by 2, nothing in DBV had to be modified:
create database DB1
go
use DB1
go
create table T (ID int not null);
insert into T(ID) values (1);
go
create database DB2
go
use DB2
go
create table T (ID int not null);
insert into T(ID) values (2);
go
create database DBV
go
use DBV
go
create view V
as
select ID
from DB1..T
go
select * from V
go
alter database DB1 modify name = DBt
go
alter database DB2 modify name = DB1
go
alter database DBt modify name = DB2
go
select * from V
Obviously better names than 1 and 2 may be used. This way, DB1 is always the one used for live and DB2 is used for any staging work.

How to report on a table based on variable in SSRS?

How do you list the details of any table (or all the tables) based on user selection? For example I want to have a dataset that contains the query:
SELECT * FROM #TableName
And then #TableName will get the list of tables from sys.tables. My database version is SQL 2008 R2.
To populate your #TableName parameter you can use:
SELECT name FROM sys.tables
Then your Dataset's Sql Statement can be an expression:
="SELECT * FROM " & Parameters!TableName.Value
However, this won't be especially useful. While the Sql Statement will execute, what are the field names going to be? This would, I imagine, be different for every table in your database. When the Sql Statement is an expression the field names aren't automatically populated and you have to add them manually. Then you have to go about mapping these fields to your table columns somehow.
So while you can theoretically do what you want to do, you can't practically use the results.
So no, you can't have one generic report for every table in your database (unless the tables for some reason have exactly the same structure).

Transferring data from one database to another

I have two databases, lets say Database A and B, with different datastructures.
In Database A there is a table contacts.
In Database B there is a table Accounts.
I want to transfer data from Database A table contacts to Database B table Accounts.
I am use SQL Server 2005 and want to write sql scripts to do this.
Can someone tell me what's the easiest and most efficient way to achieve this:
a) If they are on the same SQL server
b) If they are on different SQL servers.
The easiest method isn't necessarily the most efficient. SSIS is likely the most efficient, as Mitch already indicated.
The easiest (if you don't know SSIS already) is to just set up a linked server to the remote DB, and SELECT the data across using four-part naming. You set up a linked server using sp_addlinkedserver and sp_addlinkedsrvlogin (check BOL for the syntax), and query as follows:
INSERT INTO MyLocalTable (ColumnList)
SELECT <Columns> FROM RemoteServer.RemoteDB.RemoteSchema.RemoteTable
Use SSIS. It will work for both local and remote cases, and will enable you to set up a transform between the tables, to map columns to lother columns etc.
Is it a one off transfer? If it's a simple transfer I write a SELECT statement to create the INSERT statements, i.e.
SELECT 'INSERT INTO Accounts (ID, Name) VALUES (' + CAST(ID as VARCHAR) + ', ''' + Name + ''')'
FROM Contacts
Run this on Database A - and it will spit out the all INSERT statements, which you copy and paste so you can run them on Database B.
Or, on the same database:
INSERT INTO DatabaseA.dbo.Accounts (ID, Name)
SELECT Id, Name
FROM DatabaseB.dbo.Contacts
Still not happy - try setting up linked servers: http://msdn.microsoft.com/en-us/library/aa213778(SQL.80).aspx

Resources