I have been pulling data from a single database that stores the data for 22 facilities together. The database has now been redesigned and there are 22 separate databases (similar) for each of the facilities that we have. How can use the same code and run it against all these databases at the same time? Like, how can I pass the same parameter and pull data from all 22 databases?
You can use CURSOR to achieve your requirement. Here I placed a sample Dynamic Insert Script which you can adjust as per your requirement. One manual task is you have to insert one by one 22 database name using script in a temporary table. The facility is that is is a one time work and you can re use the script when ever it is required.
--The first step will be creating a Table variable
--where you will INSERT all your database names
--for a further loop as below-
DECLARE #DbName VARCHAR(200)
DECLARE #DatabaseList TABLE (DbName VARCHAR(200))
INSERT INTO #DatabaseList (DbName) VALUES('db_name_1')
INSERT INTO #DatabaseList (DbName) VALUES('db_name_2')
--.......................
INSERT INTO #DatabaseList (DbName) VALUES('db_name_22')
--Now you can use CURSOR to generate the loop
--and execute your required script as shown below
DECLARE db_cursor CURSOR FOR
SELECT DbName FROM #DatabaseList
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #DbName
WHILE ##FETCH_STATUS = 0
BEGIN
--HERE You need to write your script That you
--Execute for all your database. I have added
--a sample script for your reference only
-- You can see the Database Name inserted in the Script Dynamically from the Loop.
--The script could be INSERT/Update/DELETE As per requirement
EXEC
(
'INSERT INTO '+#DbName+'.dbo.<Your_table_Name_Here>
SELECT * FROM master.dbo.<Your_table_Name_Here> '
)
--END OF Dynamic Part
FETCH NEXT FROM db_cursor INTO #DbName
END
CLOSE db_cursor
DEALLOCATE db_cursor
I have created a batch script which prints information on the table into a label and saves it into pdf. At the moment, I am giving the script a number, which is the ItemCode and it prints out the rest of the information in the table.
Well now I'm going much further, my goal is to run the script each time the table is modified, or a new row is added or even if a single field is modified. When this happens it would check which row has been modified and It would run the script with the ItemCode which has been modified.
Been looking for something similar to this but couldn't find anything precise enough, so any help would be nice!
The code below is part of a trigger I am using. It writes old values and new values into a special table to track all important changes. The updated_idx is send with the SQL command to tell, what user is doing it.:
USE [Demo] -- database
GO
/****** Object: Trigger [dbo].[update_Address] Script Date: 26.07.2018 11:16:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[update_Address] ON [dbo].[Address] for UPDATE AS
DECLARE #fieldname varchar(128) = '- empty -'
DECLARE #newValue varchar(2048) = '- empty -'
DECLARE #oldValue varchar(2048)= '- empty -'
DECLARE #Updated int = datediff(s,'01/01/1970',SYSUTCDATETIME())
DECLARE #Updated_IDX int = -1
DECLARE #ID int = -1
DECLARE db_cursor CURSOR FOR SELECT Address_id, Updated_IDX FROM inserted
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #ID, #Updated_IDX -- this takes the current id
WHILE ##FETCH_STATUS = 0
BEGIN
SET NOCOUNT ON
If UPDATE([ZipCode])
BEGIN
SELECT #OldValue=b.ZipCode, #NewValue=a.ZipCode FROM inserted a, deleted b
IF #NewValue <> #OldValue
BEGIN
INSERT INTO TransactionLog ([ID],[TableName],[Type],[FieldName],[newValue],[oldValue],[Updated],[Updated_IDX]) values (#ID,'Address','U','ZipCode',#newValue,#oldValue,#Updated,#Updated_IDX);
END
END
If UPDATE([City])
BEGIN
SELECT #OldValue=b.City, #NewValue=a.City FROM inserted a, deleted b
IF #NewValue <> #OldValue
BEGIN
INSERT INTO TransactionLog ([ID],[TableName],[Type],[FieldName],[newValue],[oldValue],[Updated],[Updated_IDX]) values (#ID,'Address','U','City',#newValue,#oldValue,#Updated,#Updated_IDX);
END
END
FETCH NEXT FROM db_cursor INTO #ID, #Updated_IDX
End
CLOSE db_cursor
DEALLOCATE db_cursor
Here is part of my script:
DECLARE #dataId int = 123
-- Here I run more SQL scripts using #dataId
Select from table A where id = #dataId
-- So on it goes in other tables and delete and update other tables
My question is there a way I can enter 100 values in #dataId and it will iterate through the script in an order? Is there a simpler way to do this in SQL Server 2008 rather then manually entering #dataId each time?
Well, according to your comment, then I guess that CURSORS are the way to go. Something like this should do:
DECLARE #dataId int
DECLARE DataIds CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR
SELECT DataId
FROM YourTableWithDataIdsHere
OPEN DataIds
FETCH NEXT FROM DataIds INTO #dataId
WHILE ##FETCH_STATUS = 0
BEGIN
-- Here I run more SQL scripts using #dataId
Select from table A where id = #dataId
-- So on it goes in other tables and delete and update other tables
FETCH NEXT FROM DataIds INTO #dataId
END
CLOSE DataIds
DEALLOCATE DataIds
My Scenario is bit different. what i am doing in my stored procedure is
Create Temp Table and insert rows it in using "Cursor"
Create Table #_tempRawFeed
(
Code Int Identity,
RawFeed VarChar(Max)
)
Insert Data in temp table using cursor
Set #GetATM = Cursor Local Forward_Only Static For
Select DeviceCode,ReceivedOn
From RawStatusFeed
Where C1BL=1 AND Processed=0
Order By ReceivedOn Desc
Open #GetATM
Fetch Next
From #GetATM Into #ATM_ID,#Received_On
While ##FETCH_STATUS = 0
Begin
Set #Raw_Feed=#ATM_ID+' '+Convert(VarChar,#Received_On,121)+' '+'002333'+' '+#ATM_ID+' : Bills - Cassette Type 1 - LOW '
Insert Into #_tempRawFeed(RawFeed) Values(#Raw_Feed)
Fetch Next
From #GetATM Into #ATM_ID,#Received_On
End
Now have to process each row in Temp Table using another Cursor
DECLARE #RawFeed VarChar(Max)
DECLARE Push_Data CURSOR FORWARD_ONLY LOCAL STATIC
FOR SELECT RawFeed
FROM #_tempRawFeed
OPEN Push_Data
FETCH NEXT FROM Push_Data INTO #RawFeed
WHILE ##FETCH_STATUS = 0
BEGIN
/*
What Should i write here to retrieve each row one at a time ??
One Row should get stored in Variable..in next iteration previous value should get deleted.
*/
FETCH NEXT FROM Push_Data INTO #RawFeed
END
CLOSE Push_Data
DEALLOCATE Push_Data
Drop Table #_tempRawFeed
What Should i write In BEGIN to retrieve each row one at a time ??
One Row should get stored in Variable..in next iteration previous value should get deleted.
Regarding your last question, if what you are really intending to do within your last cursor is to concatenate RawFeed column values into one variable, you don't need cursors at all. You can use the following (adapted from your SQL Fiddle code):
CREATE TABLE #_tempRawFeed
(
Code Int IDENTITY
RawFeed VarChar(MAX)
)
INSERT INTO #_tempRawFeed(RawFeed) VALUES('SAGAR')
INSERT INTO #_tempRawFeed(RawFeed) VALUES('Nikhil')
INSERT INTO #_tempRawFeed(RawFeed) VALUES('Deepali')
DECLARE #RawFeed VarChar(MAX)
SELECT #RawFeed = COALESCE(#RawFeed + ', ', '') + ISNULL(RawFeed, '')
FROM #_tempRawFeed
SELECT #RawFeed
DROP TABLE #_tempRawFeed
More on concatenating different row values into a single string here: Concatenate many rows into a single text string?
I am pretty sure that you can avoid using the first cursor as well. Please, avoid using cursors, since the really hurt performance. The same result can be achieved using set based operations.
I have a condition where I need to pull id's from one master table and then based on that value pull values from two different tables and then update/insert into third table with these values.
I am using cursor to loop through the records in master table however I feel like this is leading to performance issue. I wanted to know if this can be done using CTE or not. I tried using CTE but it is non recursive and I am totally lost where I am going wrong.
Here is how my stored procedure is -
//
BEGIN
declare #variables char(10);
DECLARE #cursor CURSOR; --DECLARE CURSOR
SET #cursor = CURSOR FOR -- SET CURSOR
-- pull in value for curso
OPEN #cursor
FETCH NEXT
FROM #cursor INTO #variables --FILL IN CURSOR TO LOOP THROUGH
WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN
--PUll values from table 1
END
BEGIN
--Pull values from table 1
-- Do some maths on the values pulled
END
BEGIN
--function/sql to update or insert
END
FETCH NEXT
FROM #cursor INTO #variables;
END
CLOSE #cursor;
DEALLOCATE #cursor;
END
//
With CTE, my code is -
//
;WITH CTE AS
(
--pull values from master table
)
BEGIN
BEGIN
-- pull values from table 1
END
BEGIN
-- Pull values from table 2, do the calculations
END
BEGIN
-- insert or update as needed.
END
//