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
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.
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
)
;
...
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
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
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.