How to add database name dynamically in a table while update statement - sql

I have 50 databases and each of them has a tblEmp table. There is one row in tblEmp table in each database. I want to update some column data in tblEmp.
I have written below script for to update one column in tblEmp table. There is a challenge in update statement. I am getting all database name by using this script.
SELECT name
FROM master.dbo.sysdatabases
and I'm looping over each row (each database), then I want to update the tblEmp table in that database.
My question is how to add database name dynamically along with Update statement. Please see my SQL scripts below.
DECLARE #totalRecords int
DECLARE #name NVARCHAR(max)
DECLARE #userData AS TABLE (dbName NVARCHAR(max))
INSERT INTO #userData
SELECT name FROM master.dbo.sysdatabases
SET #totalRecords = ##rowcount
WHILE (#totalRecords > 0)
BEGIN
DECLARE #emptextout NVARCHAR(max)
SELECT TOP 1 #name = dbName FROM #userData
DECLARE #empdefaulttext nvarchar(max) = (N'SELECT #emptextout = CAST(empInfo AS NVARCHAR(max)) FROM '+#name +'.dbo.tblEmp')
EXECUTE sp_executesql #empdefaulttext,#Params=N'#emptextout NVARCHAR(max) OUTPUT', #emptextout = #emptextout OUTPUT
-- Here in update statement how to add database name dynamically. It should be as Update **DBName.dbo.tblEmp** set..
UPDATE tblEmp
SET empInfo = REPLACE(#emptextout, 'Rajesh', 'InfoRajesh')
SET #totalRecords = #totalRecords - 1
DELETE FROM #userData
WHERE dbname = #name
END

As Dale K mentioned:
set #empdefaulttext = N'Update '+#name +N'.dbo.tblEmp
SET empInfo = REPLACE(#emptextout, ''Rajesh'', ''Kuthrapali'')'
EXECUTE sp_executesql #empdefaulttext,#Params=N'#emptextout NVARCHAR(max) OUTPUT', #emptextout = #emptextout OUTPUT

Related

How to dynamically provide column name and update the record in SQL Server?

I have a table like this
I want to store column name in varibale #myColumn and then use Update command. How can this be done ? Is it possible ?
DECLARE #myColumn varchar(20)
SET #myColumn = 'State'
UPDATE Country SET #myColumn = 'Florida' WHERE Id = 1
Update:
I asked this question for using on my local test database for my special requirement only. I wanted to know if that was possible. As some have mentioned about XY problem, I want to let everyone know this is a specific requirement for my local test database and is not for professional use.
To dynamically use the name of a column you'll need Dynamic SQL.
Here's an example:
DECLARE #myColumn SYSNAME
, #myValue VARCHAR(20)
, #myId INT;
DECLARE #DynSql NVARCHAR(MAX)
, #UpdateSql NVARCHAR(MAX)
, #UpdateParams NVARCHAR(MAX);
SET #myColumn = 'State';
SET #myValue = 'Florida';
SET #myId = 1;
SET #UpdateSql = 'UPDATE Country'+CHAR(10)
+ 'SET [COLUMN] = #Value' +CHAR(10)
+ 'WHERE Id = #Id';
SET #UpdateParams = '#Value varchar(20), #Id int';
SET #DynSql = REPLACE(#UpdateSql, '[COLUMN]', QUOTENAME(#myColumn));
-- SELECT #DynSql As DynSql;
EXECUTE sp_executesql #DynSql, #UpdateParams
, #Value = #myValue
, #Id = #myId;
SELECT * FROM Country WHERE ID = 1;
ID
CountryName
State
1
United States of America
Florida
Test on db<>fiddle here
Yes, it's possible with some dynamic SQL. If you have complete control in the process, you can try this solution:
Let's create a temp table to show:
create table #temp ([id] int, [state] varchar(10));
Insert into #temp
SELECT 1 as ID, null as [state]
select * from #temp
Now that's created, let's try
DECLARE #myColumn varchar(20), #sql varchar(400)
SET #myColumn = '[state]'
set #sql = CONCAT('Update #temp SET ',#myColumn ,'= ''FLORIDA'' where ID = 1')
exec(#sql)
Check the results
select * from #temp
If you don't have complete control over the process, you need to save your code from SQL Injection.

How to Execute script in multiple databases at once

In Sql Server
I have sample script
Declare #V table (name varchar(100))
INSERT INTO #V(name)
select name from sys.databases where database_id > 6
select NAME from #V
If I execute this Script I get the user databases list
In my instance I have below Databases :
DatabaseName
mohan
Ravi
How can I dynamically append the Database names to below script and execute the script in below Databases
Declare #V table (ID INT,name varchar(100))
INSERT INTO #V(Id,name)
select ROW_NUMBER()OVER(ORDER BY NAME),name from sys.databases where database_id > 6
DECLARE #LoopCounter INT , #MaxId INT,
#Name NVARCHAR(100)
SELECT #LoopCounter = min(id) , #MaxId = max(Id)
FROM #V
WHILE(#LoopCounter IS NOT NULL
AND #LoopCounter <= #MaxId)
BEGIN
SELECT #Name = Name
FROM #V WHERE Id = #LoopCounter
PRINT #Name
SET #LoopCounter = #LoopCounter + 1
END
DECLARE #DatabaseName VARCHAR(50) = #Name
, #SQL NVARCHAR(MAX);
SET #SQL = N'USE ' + QUOTENAME(#DatabaseName)
+'CREATE TABLE T(ID INT)';
--PRINT(#SQL);
EXECUTE(#SQL);
So in all user databases Table will be created . I have tried with sp_msforeachdb
script :
DECLARE #Sql AS VARCHAR(4000)
SET #Sql = 'IF ''?'' NOT IN (''master'',''tempdb'',''model'',''msdb'',''ReportServer'',''ReportServerTempDB'')
EXECUTE ('' USE [?] CREATE TABLE T (ID INT)'')'
EXEC sp_MSforeachdb #command1 = #Sql
But I'm looking for looping script .How to append those names to the Script
No need for a loop here. You can generate the entire statement in one pass. This query populates a var that contains multiple USE and CREATE TABLE statements:
DECLARE #Qry NVARCHAR(MAX) = '';
-- Build dynamic SQL statement here.
-- 1 Row returned per target database .
SELECT
#Qry +=
'
USE' + QUOTENAME(Name) + ';
CREATE TABLE T
(
ID INT
)
;
'
FROM
sys.Databases
WHERE
database_id > 6
;
-- Remove comments from last line when happy with query.
PRINT #Qry
--EXECUTE sp_ExecuteSQL #Qry
Returns
USE [X];
CREATE TABLE T
(
ID INT
)
;
USE [Y];
CREATE TABLE T
(
ID INT
)
;
...

Update a Table with Dynamic SQL results within Stored Procedure

I have a table EPFReport where I need to fill the tables with a stored procedure.
ALTER procedure [dbo].[getEPFData] #EPFCol varchar(max) , #empID varchar(max)
AS
DECLARE #sql nvarchar(max) ;
DECLARE #sql2 nvarchar(max);
set #sql = 'SELECT c.employeeID,c.empName, c.month,#sql1 from Common c where c.employeeID='+#empID
set #sql2= 'SELECT ' + #EPFCol + ' FROM Common where employeeID='+#empID
truncate table EPFReport;
INSERT into EPFReport (empID, empName, monthVal)
execute(#sql);
Up to here the requirement is fulfilled where the results of the query #sql will be inserted to the table. Now I need to update it with #sql2 query, so the question is how to execute a query within a stored procedure for an update statement?
PS: for insert I've used
INSERT into EPFReport (empID, empName, monthVal)
execute(#sql);
Also here a set of results are returned (for each month). Not one row or cell of result. So assigning to a variable and updating doesn't work.
Update: the table contains these columns
[empID] [empName] [EPFItemValues] [monthVal]
First query updates only 3 columns , and the second query should update the column EPFItemValues.
Try;
Based on your comment, the following should work;
DECLARE #ID int = (Select MAX(ID) From EPFReport) // or SCOPE_IDENTITY
Update EPFReport
set EPFItemValues = #sql2
where ID = #ID

Selecting a database from a variable

So I have two databases that have no relationship between them. The first one is where my dbo.Clients exists and has a column of the database name of the second db . My thought was to select the dbName from the Clients then use that variable to select data from the second database.
The query doesnt run can some one shed a little light? Thanks.
#dbName varchar(50) OUTPUT,
#clientID varchar(50)
AS
BEGIN
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT * FROM sql02.iproconfig4.dbo.Clients
SET #dbName = (SELECT Clients.ClientDatabase FROM sql02.iproconfig4.dbo.Clients WHERE ClientID = #clientID)
SELECT * FROM sql02.#dbName.dbo.Discovery
END
You will need to use dynamic SQL to accomplish this:
DECLARE #sql nvarchar(max)
SET #sql = 'SELECT * FROM sql02.' + #dbName + '.dbo.Discovery'
EXEC sp_executesql #sql

SQL Table selection

I'm trying to create some means of dynamically selecting the table for a procedure to run on based on an ID sent to the database. Something like :
#TableId int
As
Declare #nameoftable varchar(50)
select #nameoftable = Nameoftable from tablelist where id = #tableid
-- returning on selected table
Select somestuff
from #nameoftable
Any ideas?
You need to use dynamic SQL
#TableId int
As
Declare #nameoftable varchar(50)
select #nameoftable = Nameoftable from tablelist where id = #tableid
-- returning on selected table
declare #sql nvarchar(1000)
set #sql = 'Select somestuff from ' + Quotename(#nameoftable)
exec(#sql)
In MS SQL Server you can use sp_executesql to execute dynamic queries. Read The Curse and Blessings of Dynamic SQL, it helped me alot.