Storing multiple rows while running a cursor in sql server - sql

I have written a cursor which picks up users from Users temporary table. It then finds out the latest transaction (based on many factors) and gives output messages and other results.
I am not able to think of an idea to store these values for every user in some collection and then return in to front end. Here is my code.
declare #cur1_patientid uniqueidentifier
declare #cur1_dueid uniqueidentifier
declare #cur1_dueamount varchar(10)
declare #cur1_patientname varchar(50)
declare #cur1_paymentday varchar(2)
declare #cur1_monthlyamount varchar(10)
--transaction table variables start
declare #trans_id uniqueidentifier
declare #trans_date datetime
declare #trans_amount float
declare #trans_type varchar(45)
declare #trans_status varchar(45)
declare #trans_patVisitid uniqueidentifier
--transaction table variables end
--declare other variables that will be used - start
declare #output_ARB_Date datetime
declare #output_check_flag bit
declare #output_msg varchar(MAX)
declare #output_difference numeric(3)
--declare other variables that will be used - end
set #output_check_flag=0
set #output_msg=''
set #output_difference=0
declare arb_cur cursor FAST_FORWARD for
select PatientId,dueid,dueamount,patientname,paymentday,monthlyamount from #ARB_Report1 where patientId
in ('D3658295-51B5-41DF-A1A4-E34B90EBD0F7','27F37F32-4984-47CC-B470-D086192D68FB')
open arb_cur
FETCH NEXT FROM arb_cur INTO #cur1_patientid,#cur1_dueid,#cur1_dueamount,#cur1_patientname,#cur1_paymentday,#cur1_monthlyamount
WHILE ##FETCH_STATUS = 0
BEGIN
--SELECT #cur1_patientid,#cur1_dueid --shows patientid,dueid of cursor1
DECLARE trans_cur CURSOR FOR
SELECT id,date,amount,type,status,patientVisitId FROM Transactions WHERE patientId=#cur1_patientid order by date desc
open trans_cur
--fetch transaction table values in local variables
FETCH NEXT FROM trans_cur into #trans_id,#trans_date,#trans_amount,#trans_type,#trans_status,#trans_patVisitid
--reset the variables-start
set #output_check_flag=0
set #output_msg=''
set #output_difference=0
set #output_ARB_Date=null
--reset the variables-end
WHILE (##FETCH_STATUS = 0)
begin
if(#trans_type='Reoccuring' and #trans_amount=#cur1_monthlyamount and #trans_patVisitid is null)
begin
if(#trans_status='Failed')
begin
--// some code
end
else if(#trans_status='Success')
begin
--// some code
end
select #cur1_patientid,#cur1_monthlyamount,#trans_amount,#output_ARB_Date,#output_msg,#output_difference,#cur1_dueamount
------ SOME INSERT STATEMENT HERE TO STORE THESE VALUES INTO A COLLECTION FOR EVERY PATIENT------
break
end
FETCH NEXT FROM trans_cur into #trans_id,#trans_date,#trans_amount,#trans_type,#trans_status,#trans_patVisitid
end
CLOSE trans_cur
DEALLOCATE trans_cur
FETCH NEXT FROM arb_cur INTO #cur1_patientid,#cur1_dueid,#cur1_dueamount,#cur1_patientname,#cur1_paymentday,#cur1_monthlyamount
END
CLOSE arb_cur
DEALLOCATE arb_cur
GO

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.

Run a Script Each time a table is modified

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

I want to create an array in sql with user ids, and create a loop which will pick user id from array

I want to create an array in sql with user ids, and create a loop which will pick user id from array. And create a user in sql db.
Please find the code below. It is not working as expected :
declare type namesarray IS VARARRAY (50) OF VARCHAR2 (10);
declare name namesarray;
declare total integer;
names = namesarray('resh1','resh2');
total = names.count;
while (i <= total)
begin
EXECUTE IMMEDIATE 'create user names(i) identified by newpass01;
dbms_output.put_line("created user 'names(i)");
end
dbms_output.put_line("cannot create user 'names(i)");
In Sql Server , it is done as below. You can use table variable.
Declare #namesarray table
(name varchar(50));
Declare #Name varchar(50);
Insert #namesarray values ('resh1');
Insert #namesarray values ('resh2');
Declare name_cur CURSOR FOR
Select name from #namesarray ;
OPEN name_cur
FETCH NEXT FROM name_cur INTO #Name
WHILE ##FETCH_STATUS = 0
BEGIN
Print #Name
FETCH NEXT FROM name_cur INTO #Name
END
CLOSE name_cur
DEALLOCATE name_cur

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

SET NOCOUNT ON and Cursors

I have a stored proc that calls several store procs, each of which insert dummy data into a single table each. It works fine except that for each loop in the cursor a single row of results is dispayed - just showing ClubcardId = 2, ClubcardId = 3 etc.
I have used the SET NOCOUNT ON but this doesn't seem to help. I'm looking for this stored proc to create several million rows so, SQL printing the result for each row will be an issue.
Could anyone please advise how to prevent the output from being displayed. I have copied the parent stored proc below. I can be sure that the display is not coming from the child stored proc - lap_CreateClubcardTransaction.
If I change:
DECLARE Clubcard_Cursor CURSOR FAST_FORWARD FOR
SELECT ClubcardId FROM Clubcard
...to:
DECLARE Clubcard_Cursor CURSOR FAST_FORWARD FOR
SELECT ClubcardId as 'TEST' FROM Clubcard
...then the I get the value 'TEST' displayed for each row of the cursor.
Here's the parent stored proc:
ALTER PROCEDURE [dbo].[lap_CreateDummyData]
AS
SET NOCOUNT ON
DECLARE #NumberOfCustomers bigint
DECLARE #NumberOfTransactions bigint
SET #NumberOfCustomers = 50000
SET #NumberOfTransactions = 10
EXEC lap_CreateCustomer #NumberOfCustomers = #NumberOfCustomers;
EXEC lap_CreateCustomerPreference #NumberOfCustomers = #NumberOfCustomers;
EXEC lap_CreateClubCard #NumberOfCustomers = #NumberOfCustomers;
EXEC lap_CreateClubCardOffer #NumberOfCustomers = #NumberOfCustomers;
--get static data details to use when creating transaction records
DECLARE #TransactionType tinyint
DECLARE #TransactionReasonID tinyint
DECLARE #TescoStoreID int
DECLARE #PartnerID bigint
DECLARE #PartnerOutletID bigint
DECLARE #ClubcardID bigint
SET #TransactionType = (SELECT TOP 1 TransactionType FROM TransactionType)
SET #TransactionReasonID = (SELECT TOP 1 TransactionReasonID FROM TransactionReason)
SET #TescoStoreID = (SELECT TOP 1 TescoStoreId FROM TescoStore)
SET #PartnerID = (SELECT TOP 1 PartnerID FROM PartnerOutlet)
SET #PartnerOutletID = (SELECT TOP 1 PartnerOutletID FROM PartnerOutlet)
DECLARE Clubcard_Cursor CURSOR FAST_FORWARD FOR
SELECT ClubcardId FROM Clubcard
OPEN Clubcard_Cursor
FETCH NEXT FROM Clubcard_Cursor
INTO #ClubcardID SET NOCOUNT ON
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC lap_CreateClubcardTransaction #NumberOfTransactions = #NumberOfTransactions, #ClubcardID = #ClubcardID, #TransactionType = #TransactionType, #TransactionReasonID = #TransactionReasonID, #TescoStoreId = #TescoStoreID, #PartnerID = #PartnerID, #PartnerOutletID = #PartnerOutletID;
FETCH NEXT FROM Clubcard_Cursor;
END;
CLOSE Clubcard_Cursor;
DEALLOCATE Clubcard_Cursor;
You need to direct the FETCH into variable inside the loop as well:
WHILE ...
BEGIN
...
FETCH NEXT FROM Clubcard_Cursor INTO #ClubcardID
END
Under no circumstances would I use a cursor to insert a million rows one row at a time. That will take hours. This is an example of a poor use of a cursor. Create a proc that will do a set-based operation.
SET NOCOUNT ON is useless inside the fetch, so remove it from there. It seems lap_CreateClubcardTransaction contains a SELECT statement inside its code. Can you check if this is true?