How to replace cursor code with CTE in sql server 2008 - sql

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
//

Related

how to print my cursor data values instead to insert in sql server?

I have following sql server cursor code to insert data.
Create table #tmp
(
Ref_Code UNIQUEIDENTIFIER,
Create_UserId UNIQUEIDENTIFIER
)
--simple cursor in sql server
Declare #Ref_Code UNIQUEIDENTIFIER , #Create_UserId UNIQUEIDENTIFIER
-- declare a cursor
DECLARE insert_cursor CURSOR FOR
SELECT Ref_Code,Create_UserId from Account_APInvoiceDetail
WHERE Ref_Code = '355199F6-0DE1-44AF-A8B2-2B1592980688';
-- open cursor and fetch first row into variables
OPEN insert_cursor
FETCH NEXT FROM insert_cursor into #Ref_Code,#Create_UserId
-- check for a new row
WHILE ##FETCH_STATUS=0
BEGIN
-- do complex operation here
Insert into #tmp
SELECT #Ref_Code,#Create_UserId
-- get next available row into variables
FETCH NEXT FROM insert_cursor into #Ref_Code,#Create_UserId
END
close insert_cursor
Deallocate insert_cursor
GO
but now i need print this data in my console as well. how can i do this?
Thanks.

SQL LOOP Pass values from Temp Table as parameters to stored procedure

Using SQL Server 2016, I have a huge query for our Finance Dept that uses #Year and #FinPeriod to match up transactions with a period. And for reporting we normally pass a single value into the stored procedure. But now we are required to populate the underlying tables with the data that would normally be generated on the fly.
Is there a loop anyone can help with please? I have a temp table with year values column and a finperiod for each of those years. I am looking to loop through this table - passing in both year and period to the stored procedure, one after the other until they have all been ran.
The stored procedure element is fine for me, just getting the loop/passing part to work would be a help.
So far I have:
declare #fiscalyearid numeric(9)
declare #FiscalYear numeric(9)
declare #FiscalMonthOfYear numeric(9)
declare #Year numeric(9)
declare #FinPeriod numeric(9)
if object_id('tempdb..#dateloop','u') is not null
drop table #dateloop
select distinct
identity(int,1,1) as ID,
FiscalYear_int, FiscalMonthOfYear
into
#dateloop
from
[DW].[DDS].[dimDate]
where
FiscalYear_int = '2018'
DECLARE C CURSOR LOCAL FAST_FORWARD FOR --
SELECT
ID, FiscalYear_int, FiscalMonthOfYear
FROM
#dateloop;
OPEN C;
FETCH C INTO #FiscalYear, #FiscalMonthOfYear;
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC [dbo].[Origen_Reporting->SSRS_Capex_Monitoring_Report_Expenditure] #Year, #FinPeriod
FETCH C INTO #Year,#FinPeriod
END
CLOSE C;
DEALLOCATE C;
Any tips would be brilliant. Thank you
I guess you want your Cursor logic to work. Below is the code you can use to loop through your dates and call proc in loop.
DECLARE C CURSOR LOCAL FAST_FORWARD FOR --
SELECT
FiscalYear_int, FiscalMonthOfYear
FROM
#dateloop;
OPEN C;
Fetch next from c into #FiscalYear, #FiscalMonthOfYear
WHILE ##FETCH_STATUS = 0
BEGIN
select #FiscalYear, #FiscalMonthOfYear --exec proc passing these values
EXEC [dbo].[Origen_Reporting->SSRS_Capex_Monitoring_Report_Expenditure] #FiscalYear, #FiscalMonthOfYear
FETCH next from c INTO #FiscalYear,#FiscalMonthOfYear
END
CLOSE C;
DEALLOCATE C;

Fetch SQL Server stored procedure output results into table

I have tried some solutions from the internet but they are not working for me .
My task is to get the out put of stored procedure into a table.The data is being inserted inside a cursor by loop . I am creating temporary table to store and display the data.
My code:
ALTER procedure [dbo].[usp_Test]
AS
SET NOCOUNT ON;
declare #caseId int;
declare #CHG_ID int;
declare #HEAR_ID int;
SET #CHG_ID = 1
set #testid = 1;
DECLARE db_cursor CURSOR FOR
SELECT C_CASE_ID
FROM table1 // tHERE WILL BE MULTIPLE CASEIDS
-- here I am trying to delete the temporary table, but it does not work
IF OBJECT_ID('tempdb..##test_temp_table') IS NOT NULL
TRUNCATE TABLE ##test_temp_table
ELSE
CREATE TABLE test_temp_table(HEAR_ID int)
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #caseId
WHILE ##FETCH_STATUS = 0
BEGIN
insert into test_temp_table
EXEC STOREDPROCTEST2 #caseId, 1, #HEAR_ID OUTPUT;
-- LOOP THROUGH THE CURSOR TO GET ALL CASE IDS
FETCH NEXT FROM db_cursor INTO #caseId
SELECT HEAR_ID FROM test_temp_table;
END
CLOSE db_cursor
DEALLOCATE db_cursor;
I have two issues:
I cannot delete the temporary table
I am not seeing any output from the temporary table
[##test_temp_table] and [test_temp_table] are two different tables. First one is a global temp table, second one is a user table. I believe you want to replace the user table with the global temp table, i.e. replace object [test_temp_table] with [##test_temp_table]. or vice versa. In the end, you have to ensure you are querying the correct table.

process each row in table in stored procedure using cursor

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.

IQ SQL Error: Correlation name 'updates_cur' not found

Hi i have a procedure with a cursor. Basically in the cursor i am getting a record and inserting it into DBA.header_balancing with certain values that was received in the cursor.
I receive this error "Error: Correlation name 'updates_cur' not found"
CREATE PROCEDURE sp_iq_bw_balancing
AS
BEGIN
DECLARE #date_Var date
SET #date_Var = CONVERT(CHAR(10),datepart(yy,getdate())||'-'||datepart(mm,getdate())||'-'||datepart(dd,getdate()))
declare updates_cur cursor
for select region
from DBA.TEST_IMPORT_CSV
OPEN updates_cur
BEGIN
/*Header */
INSERT INTO DBA.header_balancing(region,store_no,start_date,tran_id,start_hour,start_minute,start_second,employee,freq_shopper,lane_no,tran_no,end_date,end_hour,end_minute,end_second,total_items,total_amount,total_tenders,load_date)
VALUES (updates_cur.region, updates_cur.store_no, updates_cur.tran_date,'9999999999','23','59','59','999999999','N','999','999999',updates_cur.tran_date,'23','59','59','1',updates_cur.iq_variance_sales,'1',date_Var)
END
CLOSE updates_cur
DEALLOCATE CURSOR updates_cur
END
go
Execute sp_iq_bw_balancing
If this is a Sybase IQ cursor then I think you need to do this, 1) change the OPEN to OPEN WITH HOLD. Then FETCH the value of "region,store_no,tran_date,iq_variance_sales INTO #region,#store_no,#tran_date,#iq_variance_sales" variables and then insert the variable values.
Also your original code above tries to insert four columns (region, store_no,tran_date,iq_variance_sales) from the cursor but the cursor SELECT only includes the first column (region)
Something like....on Sybase IQ
CREATE PROCEDURE sp_iq_bw_balancing
AS
BEGIN
DECLARE #region VARCHAR
DECLARE #store_no VARCHAR
DECLARE #tran_date DATE
DECLARE #iq_variance_sales VARCHAR
DECLARE #date_Var date
SET #date_Var = CONVERT(CHAR(10),datepart(yy,getdate())||'-'||datepart(mm,getdate())||'-'||datepart(dd,getdate()))
declare updates_cur cursor
for select region,store_no,tran_date,iq_variance_sales
from DBA.TEST_IMPORT_CSV
OPEN updates_cur WITH HOLD
FETCH updates_cur INTO #region,#store_no,#tran_date,#iq_variance_sales
WHILE (##sqlstatus = 0)
BEGIN
/*Header */
INSERT INTO DBA.header_balancing(region,store_no,start_date,tran_id,start_hour,start_minute,start_second ,employee,freq_shopper,lane_no,tran_no,end_date,end_hour,end_minute,end_second,total_items,total_amount,total_tenders,load_date)
VALUES (#region, #store_no, #tran_date,'9999999999','23','59','59','999999999','N','999','999999',#tran_date,'23','59','59','1',#iq_variance_sales,'1',date_Var)
FETCH NEXT updates_cur INTO #region,#store_no,#tran_date,#iq_variance_sales
END
CLOSE updates_cur
DEALLOCATE CURSOR updates_cur
END