Executing Dynamic SQL Using A Results Set - sql

I'm using SQL Server and I want to construct a dynamic SQL statement. I have several databases that are exact clones of each other e.g. TestDatabase1 is the same as TestDatabase2 and etc. Since the schemas and tables in all of the cloned databases are exactly the same, I want to execute a SQL statement that updates each table. Here's the pseudo-code:
for each table x in a test database
update x.SomeColumn
I have code to grab the databases:
SELECT name
FROM sys.databases
WHERE name LIKE '%Test%'
but now I don't know what to do with that data. How can I update each table in each database?

You can use sp_MSforeachtable to run Update statements against every table in a database. For example:
-- First set the database you want to use:
USE TempDatabase1
GO
EXEC sp_MSforeachtable 'UPDATE ? SET SomeColumn = 2'
GO
USE TempDatabase2
GO
EXEC sp_MSforeachtable 'UPDATE ? SET SomeColumn = 2'
GO

Related

How do I update triggers across multiple databases?

I have a query that I can select the databases from the sys.databases with the triggers that I wish to update. From there I can create a cursor. However when I go into the cursor to update my triggers using a dynamic db name #DatabaseExecuteName that is set to MyDatabaseName.dbo I receive the error ''CREATE/ALTER TRIGGER' does not allow specifying the database name as a prefix to the object name.' Because I am in a cursor I am not able to execute a USE MyDatabaseName ... GO, the GO statement is not allowed inside the CURSOR. I have tried SQLCMD MODE :setvar DatabaseName "MyDatabaseName" with USE [$(DatabaseName)]; to try to set the use database. I feel I am very close however my strength is not SQL queries. I could use some assistance on what I am missing.
You can nest EXEC calls so that you can use a USE and then execute a further statement and you don't need to use GO to seperate the batches. This is a complete script to demonstrate the technique:
create database DB1
go
create database DB2
go
use DB2
go
create table T1 (ID int not null)
go
create table T2 (ID int not null)
go
use DB1
go
exec('use DB2; exec(''create trigger T_T on T1 after insert as
insert into T2(ID) select i.ID from inserted i'')');
select DB_NAME()
insert into DB2..T1(ID) values (1),(2);
select * from DB2..T2
Which then shows that this connection is still in the DB1 database, but the trigger was successfully created on the T1 table within the DB2 database.
What you have to watch for is getting your quote-escaping correct.

How to redirect a request for DB1 to DB2

Suppose I have two databases named DB1 and DB2. In DB1, there is a table named Student, In DB2, there is a stored procedure named SP1. In SP1, I am selecting data of Student Table using below query :
Select *from DB1.dbo.Student.
I have more than 300 stored procedures having above said cross database communication. Now, I want to change my database from DB1 to DB3 that is identical to DB1 from data and schema perspective.
For this, I also have to modify all 300 stored procedures that are having fully-qualified database name. Now, the query will likely to be as follows :
Select *from DB3.dbo.Student
I don't want to change all stored procedure to point DB3 now, also don't want to change my queries written in stored procedure into dynamic SQL (I know this can be done by creating dynamic SQL).
Is it possible if We run DB1.dbo.Student, It will redirect to DB3.dbo.Student. Any intermediate layer or any SQL setting.
It'll be very big help for me. Thanks In Advance !!
If the purpose of your database renaming is to migrate a database, then why not rename the databases themselves?
e.g. say rename DB1 to DB1_old and then rename DB3 to DB1
I would simply script out all stored procedures using SQL Server script generator tool. Then do a find replace on the script and find text ‘DB1.dbo.’ and replace with ‘DB3.dbo.’
In the future you might want to consider using synonyms to reference external tables then you would only have to update the synonyms instead of all of your procedures. Please see following MSDN article on synonyms:
https://msdn.microsoft.com/en-us/library/ms187552.aspx
Example use of synonym:
USE [DB1]
GO
-- Create a synonym for table A located in DB2.
CREATE SYNONYM [dbo].[External_TableA] FOR [DB2].[dbo].[TableA]
GO
-- Synonym is pointing to TableA in DB2 , select statement will return data from DB2 tabla A.
SELECT *
FROM [External_TableA]
GO
-- Point the Synonym to same table but on DB3
DROP SYNONYM [dbo].[External_TableA]
CREATE SYNONYM [dbo].[External_TableA] FOR [DB3].[dbo].[TableA]
GO
-- No update was needed on views or stored procedure.
-- Synonym is pointing to TableA in DB3 , select statement will return data from DB3 tabla A.
SELECT *
FROM [External_TableA]
The follow query will generate the required DROP and CREATE script to remap your synonyms from the old database to the new database.
DECLARE #oldDB NVARCHAR(100) = 'DB2';
DECLARE #newDB NVARCHAR(100) = 'DB3';
SELECT 'DROP SYNONYM [dbo].[' + name + ']' AS [Drop Script]
,'CREATE SYNONYM [dbo].[' + name + '] FOR ' + REPLACE(base_object_name, #oldDB, #newDB) AS CreateScript
FROM sys.synonyms
ORDER BY name
its better to use USE Keyword
use [database name you want to access]
Queries and stored procedure you want to use
GO
eg
use [db1]
select *from yourTableName
exec yourStoredProcedure parm1,parm2,....
Go

Query to copy rows from sql server to another sql server

I have two sql servers, SE1 and SE2, they are basically having the same schema, but each one has its own usability.
I need to find a query to copy some rows from SE1.Table1 Where Destination Like '%HR%' to SE2.Table2.
Is there such query ??
Thx in advance.
I find the easiest way is to add a remote connection from one to the other. So, go to the second server and do:
sp_addlinkedserver SE1
Then you can go to the database you want to use and do something like:
insert into database.dbo.Table1(<column list>)
select <column list>
from SE1.database.dbo.Table1
where col like '%HR%';
This uses the four-part naming convention to access the remove table.
SELECT * into tr FROM OPENROWSET( 'SQLOLEDB',
'Server=10.10.1.89\SQLEXPRESSR2;UID=sa;PWD=password',
'SET FMTONLY OFF;SET NOCOUNT ON; exec DBASE89.dbo.Getdata #UID=''21'''
)
select * from tr
consider 10.10.1.89\SQLEXPRESSR2 as remote server, we need to create stored procedure with select command for required data.
Here tr is Temp table, when execute above query the result will stored in tr table. From this tr table we can copy to required table in local server.
Note:
in 10.10.1.89\SQLEXPRESSR2 server, need to enable the OleAutomationEnabled set as True in SurfaceAreaConfiguration.

run sql update statement on multiple databases

I have the following SQL update:
UPDATE [Shop_Benelux_2012].[dbo].[StringResource]
SET [ConfigValue] = ''
WHERE [Name] = 'default.aspx.1'
GO
I have 10 databases i need to run this statement on.
My DB's look like this:
Shop_DE_2012
Shop_FR_2012 ...
how can i run the statement on all databases without manually running it on each db in management studio?
Quick and dirty
EXEC sp_MSForEachDB '
USE ?
IF DB_NAME() LIKE ''Shop%''
UPDATE [dbo].[StringResource]
SET [ConfigValue] = ''''
WHERE [Name] = ''default.aspx.1''
'
Note: I use a 2 part name, without "Shop_Benelux_2012"
I have a view that wraps all databases together that allows me to select, insert, update, or delete from any of them with one query. These are known as partitioned views. You'll want to read this.
http://technet.microsoft.com/en-us/library/ms190019(v=sql.105).aspx

use output of SQL statement as the table to run a query on

I believe what I am attempting to achieve may only be done through the use of Dynamic SQL. However, I have tried a couple of things without success.
I have a table in database DB1 (lets say DB1.dbo.table1, in a MS SQL server) that contains the names of other databases in the server (DB2,DB3, etc). Now, all the dbs listed in that table contain a particular table (lets call it desiredTable) which I want to query. So what I'm looking for is a way of creating a stored procedure/script/whatever that queries DB1.dbotable1 for the other DBs and then run a statement on each of the dbs retrieved, something like:
#DBNAME = select dbName from DB1.dbo.table1
select value1 from #DBNAME.dbo.desiredTable
Is that possible? I'm planning on running the sp/script in various systems DB1.dbo.table1 being a constant.
You need to build a query dinamically and then execute it. Something like this:
DECLARE #MyDynamicQuery VARCHAR(MAX)
DECLARE #MyDynamicDBName VARCHAR(20)
SELECT #MyDynamicDBName = dbName
FROM DB1.dbo.table1
SET #MyDynamicQuery = 'SELECT value1 FROM ' + #MyDynamicDBName + '.dbo.desiredTable'
EXEC(#MyDynamicQuery)
You can use the undocumented stored procedure, sp_MSForEachDB. The usual warnings about using an undocumented stored procedure apply though. Here's an example of how you might use it in your case:
EXEC sp_MSForEachDB 'SELECT value1 FROM ?.dbo.desiredTable'
Notice the use of ? in place of the DB name.
I'm not sure how you would limit it to only DBs in your own table. If I come up with something, then I'll post it here.