Adding values to an existing table by using Cursor - sql

By running this code its working, but when I add more values to the table it's not working anymore. I appreciate any help, thank you.
This code works perfectly:
declare #id int
declare #empid int
set #id = 0
declare #schedindate datetime
declare #ss nvarchar(100)
declare #indice nvarchar(2)
declare #FromDate datetime
declare #ToDate datetime
declare #TimeInR datetime
declare #TimeOutR datetime
declare #departmentID int
declare #PositionID int
declare #BranchID int
declare #SupervisorID int
declare #GradeID int
declare #Custom1ID int
declare #Custom2ID int
declare #PayClassID int
declare #EmploymentType int
set #FromDate = '2009-01-14'
set #ToDate = '2010-01-30'
delete from table1
declare cc cursor for select distinct empid from ta_timecard where schedindate between #FromDate and #ToDate
open cc
fetch next from cc into #empid
while (##fetch_status = 0)
begin
set #id = #id + 1
insert into table1 (ID, EmpID) values (#id, #empid)
declare cc2 cursor for select distinct departmentid from ta_timecard where empid = #empid and schedindate between #FromDate and #ToDate
open cc2
fetch next from cc2 into #departmentID
while (##fetch_status = 0)
begin
set #indice = cast(datediff(day, #fromdate, #schedindate) as nvarchar(4))
set #ss = 'update table1 set departmetid = ' + convert(nvarchar(4), #departmentID)
+ ' where empid = ' + convert(nvarchar(4), #empid)
execute sp_executesql #ss
fetch next from cc2 into #departmentID
end
close cc2
deallocate cc2
fetch next from cc into #empid
end
close cc
Deallocate cc
GO
But when I add more values to the table I got the first row only affected
declare #id int
declare #empid int
set #id = 0
declare #schedindate datetime
declare #ss nvarchar(100)
declare #indice nvarchar(2)
declare #FromDate datetime
declare #ToDate datetime
declare #TimeInR datetime
declare #TimeOutR datetime
declare #departmentID int
declare #PositionID int
declare #BranchID int
declare #SupervisorID int
declare #GradeID int
declare #Custom1ID int
declare #Custom2ID int
declare #PayClassID int
declare #EmploymentType int
set #FromDate = '2009-01-14'
set #ToDate = '2010-01-30'
delete from table1
declare cc cursor for select distinct empid from ta_timecard where schedindate between #FromDate and #ToDate
open cc
fetch next from cc into #empid
while (##fetch_status = 0)
begin
set #id = #id + 1
insert into table1 (ID, EmpID) values (#id, #empid)
declare cc2 cursor for select distinct departmentid, branchid from ta_timecard where empid = #empid --and schedindate between #FromDate and #ToDate
open cc2
fetch next from cc2 into #departmentID, #BranchID--,#PositionID
while (##fetch_status = 0)
begin
set #indice = cast(datediff(day, #fromdate, #schedindate) as nvarchar(4))
set #ss = 'update table1 set departmetid = ' + convert(nvarchar(4), #departmentID)
+', branchid = ' + convert(nvarchar(4), #BranchID)
--+ ', positionid = ' + convert(nvarchar(4), #PositionID)
+ ' where empid = ' + convert(nvarchar(4), #empid)
print(#ss)
execute sp_executesql #ss
fetch next from cc2 into #departmentID, #BranchID--, #PositionID
end
close cc2
deallocate cc2
fetch next from cc into #empid
end
close cc
Deallocate cc
GO
Edited:
this is the table ta_TimeCard

you need check #BranchID on NULL values
+ ISNULL(', branchid = ' + convert(nvarchar(4), #BranchID), '')

Please change your query from
set #ss = 'update table1 set departmetid = '
to
set #ss = 'update table1 set departmentid = '
the n might affect your result

Related

Using cursor to loop through a table variable in SQL Server

I have a parameter of a stored procedure which gets some data in the format
1/1/2018-2/1/2018,2/1/2018-3/1/2018,3/1/2018-4/1/2018,4/1/2018-5/1/2018,5/1/2018-6/1/2018,6/1/2018-7/1/2018,7/1/2018-8/1/2018,8/1/2018-9/1/2018,9/1/2018-10/1/2018,
10/1/2018-11/1/2018,11/1/2018-12/1/2018,12/1/2018-12/31/2018
I have a function which splits the data based on the , character and stores the results into a table variable as shown here:
declare #SPlitDates table(ItemNumber int, Item nvarchar(max))
insert into #SPlitDates
select *
from dbo.SPlitFunction(#RequestData, ',')
After this I have to perform certain operations on the data range so I use cursors to loop through the temp table as shown below
DECLARE cur CURSOR FOR
SELECT Item
FROM #SPlitDates
ORDER BY ItemNumber
OPEN cur
FETCH NEXT FROM cur INTO #monthStart
WHILE ##FETCH_STATUS = 0
BEGIN
-- Some operation
END
The max data points that I will get in the temp table is the date range for 12 months.
My question is that could I be using something else apart from cursors to improve performance or it doesn't matter when the dataset is really this small.
Thanks
Edit - To show operation inside the cursor
declare #SPlitDates table(ItemNumber int, Item nvarchar(max))
insert into #SPlitDates
select *
from dbo.SPlitFunction(#RequestData, ',')
declare #SPlitDatesData table (ItemNumber varchar(100), Item nvarchar(max))
declare #SPlitDatesAvgData table(Code nvarchar(100), Val decimal(18,2))
declare #dataFilter as nvarchar(max),
#SQL as nvarchar(max);
declare #monthStart nvarchar(100)
declare #count int
set #count = 0
--Declaring a cursor to loop through all the dates as defined in the requested quarter
DECLARE cur CURSOR FOR
SELECT Item
FROM #SPlitDates
ORDER BY ItemNumber
OPEN cur
FETCH NEXT FROM cur INTO #monthStart
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #Period NVARCHAR(100)
SET #Period = #monthStart
INSERT INTO #SPlitDatesData
--split the dates to get the start and the end dates
SELECT *
FROM dbo.SPlitFunction(#Period, '-')
DECLARE #PeriodStart NVARCHAR(100)
DECLARE #PeriodEnd NVARCHAR(100)
SET #PeriodStart = (SELECT Item FROM #SPlitDatesData WHERE ItemNumber = 1)
SET #PeriodEnd = (SELECT Item FROM #SPlitDatesData WHERE ItemNumber = 2)
DELETE FROM #SPlitDatesData
--add the start and end dates to the filter
SET #dataFilter = 'StatusDate between convert(datetime,('''+#PeriodStart+'''))
and DATEADD(dy, 1, convert(datetime,('''+#PeriodEnd+''')))'
SET #count = #count +1;
SET #SQL = 'INSERT INTO #BidAverageCycleCalculation (SortOrder, Code, Data)
VALUES (#count,
''SL Payroll'',(select dbo.GetAverageCycleBetweenBids('''+#PeriodStart+''',
'''+#PeriodEnd+''',''SL''))
)'
EXEC SP_ExecuteSQL #SQL, N'#count int', #count;
SET #count = #count +1;
SET #SQL = 'INSERT INTO #BidAverageCycleCalculation (SortOrder, Code, Data)
VALUES (#count,
''GV Payroll'',(select dbo.GetAverageCycleBetweenBids('''+#PeriodStart+''',
'''+#PeriodEnd+''',''GV''))
)'
EXEC SP_ExecuteSQL #SQL , N'#count int', #count;
SET #count = #count +1;
SET #SQL = 'Insert into #BidAverageCycleCalculation (SortOrder,Code,Data)
Values (#count,
''Global Payroll'',(select dbo.GetAverageCycleBetweenBids('''+#PeriodStart+''',
'''+#PeriodEnd+''',''GVS''))
)'
EXEC SP_ExecuteSQL #SQL, N'#count int', #count;
SET #count = #count +1;
SET #SQL = 'Insert into #BidAverageCycleCalculation (SortOrder,Code,Data)
Values (#count,
''TimeHCM'',(select dbo.GetAverageCycleBetweenBids('''+#PeriodStart+''',
'''+#PeriodEnd+''',''Time''))
)'
EXEC SP_ExecuteSQL #SQL, N'#count int', #count;
delete from #SPlitDatesAVgData
FETCH NEXT FROM cur INTO #monthStart
END
CLOSE cur
DEALLOCATE cur
This uses two parts - first convert your string into a table, then do bulk inserts into your destination. No need for cursors.
** Please excuse any syntax errors as I'm doing it without access to your actual tables or functions so cant test it, but you get the idea
declare #in varchar(max)
set #in= '1/1/2018-2/1/2018,2/1/2018-3/1/2018,3/1/2018-4/1/2018,4/1/2018-5/1/2018,5/1/2018-6/1/2018,6/1/2018-7/1/2018,7/1/2018-8/1/2018,8/1/2018-9/1/2018,9/1/2018-10/1/2018,10/1/2018-11/1/2018,11/1/2018-12/1/2018,12/1/2018-12/31/2018'
declare #xml xml;
set #xml= convert(xml,'<r><f>'+replace(replace(#in,',','</t></r><r><f>'),'-','</f><t>') +'</t></r>')
declare #t table(id int identity, f date, t date)
insert #t
select
Tbl.Col.value('f[1]', 'date') f,
Tbl.Col.value('t[1]', 'date') t
FROM #xml.nodes('//r') Tbl(Col)
select * from #t
declare #count int;
select #count=count(*) from #t
INSERT INTO #BidAverageCycleCalculation (SortOrder, Code, Data)
select id, 'SL Payroll',(select dbo.GetAverageCycleBetweenBids(f,t,'SL')) from #t
INSERT INTO #BidAverageCycleCalculation (SortOrder, Code, Data)
select id+#count,'GV Payroll',(select dbo.GetAverageCycleBetweenBids(f,t,'GV')) from #t
INSERT INTO #BidAverageCycleCalculation (SortOrder, Code, Data)
select id+#count*2,'Global Payroll',(select dbo.GetAverageCycleBetweenBids(f,t,'GVS')) from #t
INSERT INTO #BidAverageCycleCalculation (SortOrder, Code, Data)
select id+#count*3,'TimeHCM',(select dbo.GetAverageCycleBetweenBids(f,t,'Time')) from #t

Unable to Create the Complete Dynamic Query using NVARCHAR(Max)

I am using NVARCHAR(MAX) to create a dynamic query.Since NVARCHAR uses 2 bytes per character, Approximately 1 billion characters can include in NVARCHAR(MAX) variable (Link Reference) .
I tried by executing stored procedure in SQL Server itself, then executing the stored procedure through the application.
Both situation dynamic query is not exceeding those character length. But only part of the Dynamic query is get executed.Because of that stored procedure throw errors to the application.
Am I missing any code ?
USE [MyDemoDB]
GO
ALTER PROCEDURE [dbo].[sp_Apply]
(
#scenarioId INT,
#userId INT,
#bookId INT
)
AS
DECLARE #BucketId INT
DECLARE #HierarchyId NVARCHAR(10)
DECLARE #Year INT
DECLARE #Month INT
DECLARE #PlanningSeason NVARCHAR(20)
DECLARE #StructureId INT = 9
DECLARE #AllocStructureId INT = 11
DECLARE #UpdatedUser INT = 2
DECLARE #InsertOne NVARCHAR(MAX)=''
DECLARE #AreaSchema NVARCHAR(40)
DECLARE #AreaCode NVARCHAR(20)
DECLARE #EmptyValue NVARCHAR(20)
SET #AreaCode = ''
SET #AreaSchema = '[dbo]'
SET #InsertOne = '
DECLARE #FGSupplySeqId INT
DECLARE #FGSupplyId NVARCHAR(10)
DECLARE #PlannedQty DECIMAL(18,2)
DECLARE #ConfirmdQty DECIMAL(18,2)
DECLARE #Year INT
DECLARE #Month INT
DECLARE #Season NVARCHAR(20)
DECLARE #MerchantId NVARCHAR(50)
DECLARE #UpdatedUser INT
DECLARE #HierarchyId NVARCHAR(10)
DECLARE #BucketId INT
DECLARE #ProductNo NVARCHAR(100)
DECLARE #LocationNo NVARCHAR(100)
SET #BucketId = '+ CAST(#BucketId AS VARCHAR) + '
SET #UpdatedUser = '+ CAST(#userId AS VARCHAR) + '
IF #BucketId = 1
BEGIN
DECLARE Supplys
CURSOR FOR
SELECT [FGSupplySeqId],[FGSupplyId] FROM ' + #AreaSchema + '.[FGSupply]
WHERE PlanningScenarioId ='+ CONVERT(VARCHAR(10),#scenarioId)+ '
OPEN Supplys
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE Allocations
CURSOR FOR
SELECT #FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,ConfirmedQty,Year,Season,ProductNo,LocationNo
FROM '+ #AreaSchema +'.[FGAllocation]
WHERE FGSupplySeqId = #FGSupplySeqId
OPEN Allocations
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Season,#ProductNo,#LocationNo
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #FGAllocationId NVARCHAR(10)
DECLARE #AllocStatus INT
SET #FGAllocationId = ''E''
SET #AllocStatus= 0
SELECT #FGAllocationId = FGAllocationId,#AllocStatus=Status
FROM ' + #AreaSchema+'.[SN_PLANNING_FGAllocation]
WHERE [HierarchyId]=#HierarchyId AND [MerchantNo]=#MerchantId AND YEAR = #Year AND [Month] IS NULL
IF #FGAllocationId = ''E''
BEGIN
-- IF #AllocStatus <> 5
INSERT INTO'+ #AreaSchema+'.[SN_PLANNING_FGAllocation]
(FinishedGoodSupplyId,FGHierarchyId,MerchantNo,PlannedQty,Year,Season,Status,IsActive,CreatedBy,UpdatedBy,CreatedOn,UpdatedOn,ProductNo,LocationNo)
VALUES(#FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#Year,#Season,0,1,#UpdatedUser,#UpdatedUser,GETDATE(),GETDATE(),#ProductNo,#LocationNo)
END
ELSE
BEGIN
-- IF #AllocStatus <> 5
UPDATE ' + #AreaSchema + '.[SN_PLANNING_FGAllocation]
SET PlannedQty = #PlannedQty ,ConfirmedQty=#ConfirmdQty,UpdatedBy=#UpdatedUser, UpdatedOn=GETDATE()
WHERE FGAllocationId = #FGAllocationId
END
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Season,#ProductNo,#LocationNo
END
CLOSE Allocations
DEALLOCATE Allocations
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
END
CLOSE Supplys
DEALLOCATE Supplys
END
IF #BucketId = 2
BEGIN
DECLARE Supplys
CURSOR FOR
SELECT [FGSupplySeqId],[FGSupplyId] FROM ' + #AreaSchema + '.[FGSupply]
WHERE PlanningScenarioId ='+ CONVERT(VARCHAR(10),#scenarioId)+ 'AND Month IS NOT NULL
OPEN Supplys
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE Allocations
CURSOR FOR
SELECT #FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,ConfirmedQty,Year, Month,Season,#ProductNo,#LocationNo
FROM '+ #AreaSchema +'.[FGAllocation]
WHERE FGSupplySeqId = #FGSupplySeqId AND Month IS NOT NULL
OPEN Allocations
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Month,#Season,#ProductNo,#LocationNo
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #FGAllocationId1 NVARCHAR(10)
SET #FGAllocationId1 = ''E''
SELECT #FGAllocationId1 = FGAllocationId,#AllocStatus=Status
FROM ' + #AreaSchema+'.[SN_PLANNING_FGAllocation]
WHERE [HierarchyId]=#HierarchyId AND [MerchantNo]=#MerchantId AND YEAR = #Year AND [Month] = #Month
IF #FGAllocationId1 = ''E''
BEGIN
-- IF #AllocStatus <> 5
INSERT INTO'+ #AreaSchema+'.[SN_PLANNING_FGAllocation]
(FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,Year,Month,Season,Status,IsActive,CreatedBy,UpdatedBy,CreatedOn,UpdatedOn,ProductNo,LocationNo)
VALUES(#FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#Year,#Month,#Season,0,1,#UpdatedUser,#UpdatedUser,GETDATE(),GETDATE(),#ProductNo,#LocationNo)
END
ELSE
BEGIN
-- IF #AllocStatus <> 5
UPDATE ' + #AreaSchema + '.[SN_PLANNING_FGAllocation]
SET PlannedQty = #PlannedQty ,ConfirmedQty=#ConfirmdQty,UpdatedBy=#UpdatedUser, UpdatedOn=GETDATE()
WHERE FGAllocationId = #FGAllocationId1
END
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Month,#Season,#ProductNo,#LocationNo
END
CLOSE Allocations
DEALLOCATE Allocations
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
END
CLOSE Supplys
DEALLOCATE Supplys
END'
print #InsertOne
EXEC(#InsertOne)
Yes, you may be facing the issue because of nvarchar limit is 4000 characters.
I also face this issue and resolved by concatenate the string and then execute.
If you select or print it only show 4000 character, but if you concatenate or append the string it must append (till 8000 character). So don't bother about this, you do not print or select just append and execute and its definitely work.
In this link this is explain.
declare #sql Nvarchar(max),
#a nvarchar(max),
#b nvarchar(max);
select #sql =N'', #a = N'a', #b = N'b';
select #sql = #sql +replicate(#a,4000) + replicate(#b, 6000);
select len(#sql)
There is one rule for this :-
SET #dynamicSQL = [concatenate various unicode strings and nvarchar
variables totalling over 4000 characters] -- MAKE SURE AT LEAST ONE OF
THE UNICODE STRINGS IS NVARCHAR(MAX), YOU CAN CAST ANY ONE ARGUMENT.
You can check this link also.
https://dba.stackexchange.com/questions/18483/varcharmax-field-cutting-off-data-after-8000-characters-sql-server-2008
Updated
I show your entire code and want to explain some things.
First of all, why you want dynamic query. Code shows that you can do it without dynamic query and also there is so much nested cursor (try to ignore it with simple query)
Still if you want to go, then I remove you extra code (I don't think that remove space will work, I had 4 union query and its very huge length and its work with this strategy after verify each part in separate window)
a.Here is another option before you read below. rather than define parameter in query, you can pass this parameter too.
begin tran
create table table1 ( id int, value varchar(10) )
insert into table1 values( 1,'001')
insert into table1 values(2, '002')
insert into table1 values( 3,'003')
insert into table1 values( 4,'004')
declare #sql nvarchar(max) , #temp nvarchar(50) = '1,2,3', #tempIntSingleValue nvarchar(50) = '2'
select * from table1
set #sql = 'select * from table1 where id in ( ' + #temp + ')'
print #sql
exec sp_executesql #sql
set #sql = 'select * from table1 where id in ( #tempInner)'
print #sql
exec sp_executesql #sql , N'#tempInner int', #tempInner = #tempIntSingleValue
rollback
b. you used same parameter in your dynamic query. so I think issue with you have to give either default value or assign value at run-time. so while concatenating your string not become null. See this example below. I am define all character to '' and int to numeric value and at last print which print something. If we not define it never print blank due to concatenate set null value.
declare #scenarioId INT = 1 ,
#userId INT = 5,
#bookId INT = 1
DECLARE #BucketId INT = 0
DECLARE #HierarchyId NVARCHAR(10)
DECLARE #Year INT
DECLARE #Month INT
DECLARE #PlanningSeason NVARCHAR(20)
DECLARE #StructureId INT = 9
DECLARE #AllocStructureId INT = 11
DECLARE #UpdatedUser INT = 2
DECLARE #InsertOne NVARCHAR(MAX) =''
DECLARE #AreaSchema NVARCHAR(40)
DECLARE #AreaCode NVARCHAR(20)
DECLARE #EmptyValue NVARCHAR(20)
SET #AreaCode = ''
SET #AreaSchema = '[dbo]'
SET #InsertOne =
'DECLARE #FGSupplySeqId INT = 5
DECLARE #FGSupplyId NVARCHAR(10) = ''''
DECLARE #PlannedQty DECIMAL(18,2) = ''''
DECLARE #ConfirmdQty DECIMAL(18,2) = ''''
DECLARE #Year INT = 2015
DECLARE #Month INT = 7
DECLARE #Season NVARCHAR(20) = ''''
DECLARE #MerchantId NVARCHAR(50) = ''''
DECLARE #UpdatedUser INT
DECLARE #HierarchyId NVARCHAR(10) = ''''
DECLARE #BucketId INT = 0
DECLARE #ProductNo NVARCHAR(100)= ''''
DECLARE #LocationNo NVARCHAR(100)
SET #BucketId = '+ CAST(#BucketId AS VARCHAR) + '
SET #UpdatedUser = '+ CAST(#userId AS VARCHAR) + '
IF #BucketId = 1
BEGIN
DECLARE Supplys
CURSOR FOR
SELECT [FGSupplySeqId],[FGSupplyId] FROM ' + #AreaSchema + '.[FGSupply]
WHERE PlanningScenarioId ='+ CONVERT(VARCHAR(10),#scenarioId)+ '
OPEN Supplys
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE Allocations
CURSOR FOR
SELECT #FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,ConfirmedQty,Year,Season,ProductNo,LocationNo
FROM '+ #AreaSchema +'.[FGAllocation]
WHERE FGSupplySeqId = #FGSupplySeqId
OPEN Allocations
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Season,#ProductNo,#LocationNo
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #FGAllocationId NVARCHAR(10)
DECLARE #AllocStatus INT
SET #FGAllocationId = ''E''
SET #AllocStatus= 0
SELECT #FGAllocationId = FGAllocationId,#AllocStatus=Status
FROM ' + #AreaSchema+'.[SN_PLANNING_FGAllocation]
WHERE [HierarchyId]=#HierarchyId AND [MerchantNo]=#MerchantId AND YEAR = #Year AND [Month] IS NULL
IF #FGAllocationId = ''E''
BEGIN
-- IF #AllocStatus <> 5
INSERT INTO'+ #AreaSchema+'.[SN_PLANNING_FGAllocation]
(FinishedGoodSupplyId,FGHierarchyId,MerchantNo,PlannedQty,Year,Season,Status,IsActive,CreatedBy,UpdatedBy,CreatedOn,UpdatedOn,ProductNo,LocationNo)
VALUES(#FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#Year,#Season,0,1,#UpdatedUser,#UpdatedUser,GETDATE(),GETDATE(),#ProductNo,#LocationNo)
END
ELSE
BEGIN
-- IF #AllocStatus <> 5
UPDATE ' + #AreaSchema + '.[SN_PLANNING_FGAllocation]
SET PlannedQty = #PlannedQty ,ConfirmedQty=#ConfirmdQty,UpdatedBy=#UpdatedUser, UpdatedOn=GETDATE()
WHERE FGAllocationId = #FGAllocationId
END
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Season,#ProductNo,#LocationNo
END
CLOSE Allocations
DEALLOCATE Allocations
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
END
CLOSE Supplys
DEALLOCATE Supplys
END
IF #BucketId = 2
BEGIN
DECLARE Supplys
CURSOR FOR
SELECT [FGSupplySeqId],[FGSupplyId] FROM ' + #AreaSchema + '.[FGSupply]
WHERE PlanningScenarioId ='+ CONVERT(VARCHAR(10),#scenarioId)+ 'AND Month IS NOT NULL
OPEN Supplys
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE Allocations
CURSOR FOR
SELECT #FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,ConfirmedQty,Year, Month,Season,#ProductNo,#LocationNo
FROM '+ #AreaSchema +'.[FGAllocation]
WHERE FGSupplySeqId = #FGSupplySeqId AND Month IS NOT NULL
OPEN Allocations
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Month,#Season,#ProductNo,#LocationNo
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #FGAllocationId1 NVARCHAR(10)
SET #FGAllocationId1 = ''E''
SELECT #FGAllocationId1 = FGAllocationId,#AllocStatus=Status
FROM ' + #AreaSchema+'.[SN_PLANNING_FGAllocation]
WHERE [HierarchyId]=#HierarchyId AND [MerchantNo]=#MerchantId AND YEAR = #Year AND [Month] = #Month
IF #FGAllocationId1 = ''E''
BEGIN
-- IF #AllocStatus <> 5
INSERT INTO'+ #AreaSchema+'.[SN_PLANNING_FGAllocation]
(FGSupplyId,FGHierarchyId,MerchantNo,PlannedQty,Year,Month,Season,Status,IsActive,CreatedBy,UpdatedBy,CreatedOn,UpdatedOn,ProductNo,LocationNo)
VALUES(#FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#Year,#Month,#Season,0,1,#UpdatedUser,#UpdatedUser,GETDATE(),GETDATE(),#ProductNo,#LocationNo)
END
ELSE
BEGIN
-- IF #AllocStatus <> 5
UPDATE ' + #AreaSchema + '.[SN_PLANNING_FGAllocation]
SET PlannedQty = #PlannedQty ,ConfirmedQty=#ConfirmdQty,UpdatedBy=#UpdatedUser, UpdatedOn=GETDATE()
WHERE FGAllocationId = #FGAllocationId1
END
FETCH NEXT
FROM Allocations
INTO #FGSupplyId,#HierarchyId,#MerchantId,#PlannedQty,#ConfirmdQty,#Year,#Month,#Season,#ProductNo,#LocationNo
END
CLOSE Allocations
DEALLOCATE Allocations
FETCH NEXT
FROM Supplys
INTO #FGSupplySeqId,#FGSupplyId
END
CLOSE Supplys
DEALLOCATE Supplys
END'
print #InsertOne
Make sure your variable don't contain quotes or double quote them.
declare #value nvarchar(100) = 'abcd''efgh'
declare #sql nvarchar(max)
-- tons of QUOTE !!!
Set #sql = N'select ''' + REPLACE(#value, '''', '''''') + '''';
print #sql
exec sp_executesql #sql
Put brackets around your object names and at least one space between into and DB:
INSERT INTO'+ #AreaSchema+'.[SN_PLANNING_FGAllocation]
-- space is missing
or you can use the QUOTENAME function QUOTENAME(#AreaSchema)
Use N'' and NVARCHAR(...) or '' and VARCHAR() but don't mix
You declare everything as NVARCHAR and then concatenate it with ''. It should be N''. You also convert/cast everything as VARCHAR. It should be NVARCHAR(...).
Dynamic SQL use a NVARCHAR string.
Make sure variable are set or have a default value
SET #BucketId = '+ CAST(#BucketId AS nVARCHAR) + '
This will return NULL because #BucketId is not set in your stored procedure. Either use a ISNULL, set it or give it a default value
You should use EXEC sp_executesql and declare variables when they are used as such
https://msdn.microsoft.com/fr-fr/library/ms188001(v=sql.120).aspx
EXEC sp_executesql #yourquery, N'#UserID int, ...', #userID = #UserId ...
Keep concatenation only when it is needed (dynamic object names)
Finally
Before trying to execute it, make sure your print output the correct query (print only show the 1st 4000 characters). If the query is incomplete, it probably means that your have an error in the code near the line where it stop.
I tried your proc and it returns nothing (NULL) the way it is unless I first init all the variables. There are also truncations because you do not use N''

The number of variables declared in the INTO list must match that of selected columns one select one into

This is a pretty straightforward error, but I can't figure out why I am getting it. I have one column selected in my declare (TABLE_NAME) and am fetching into one variable (#cTableName). What gives?
CREATE PROCEDURE [dbo].[updateNumbers_ArchiveDB]
(
#accountNumber varchar(50),
#padding varchar(50),
#proc_dateStart datetime,
#proc_dateEnd datetime
)
AS
DECLARE #cTableName varchar(50)
DECLARE CursorYearlyTables CURSOR FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME like 'Archive[12]%' and len(TABLE_NAME) = 14
ORDER BY TABLE_NAME;
-- =============================================
-- Open the cursor and iterate over the monthlies
-- =============================================
OPEN CursorYearlyTables
fetch next from CursorYearlyTables into #cTableName
while (##fetch_status <> -1)
BEGIN
SET NOCOUNT ON;
declare #q varchar(1000);
set #q = 'Update' + #cTableName +
'SET LogicalAccount = #padding + #accountNumber' +
'WHERE ProcessDate BETWEEN CAST(#proc_dateStart AS DATE) AND CAST(#proc_dateEnd AS DATE)'
exec(#q)
fetch next from CursorYearlyTables into #cTableName
END
close CursorYearlyTables;
DEALLOCATE CursorYearlyTables;
Could you try it with these lines in the cursor
declare #q nvarchar(max);
set #q = 'Update ' + #cTableName +
'SET LogicalAccount = '+#padding + #accountNumber +
'WHERE ProcessDate BETWEEN CAST('''+CONVERT(VARCHAR(20),#proc_dateStart)+''' AS DATE) AND CAST('''+CONVERT(VARCHAR(20),#proc_dateEnd)+''' AS DATE)'
exec sp_executesql #q
to account for SQL_Injection DavidG commented:
declare
#q nvarchar(max) = 'update '+#cTableName+' SET LogicalAccount = #a where ProcessDate BETWEEN CAST(#b AS DATE) AND CAST(#c AS DATE))',
#param1 nvarchar(100) = #padding+ #accountNumber,
#ParamDefinition nvarchar(500) = N'#a varchar(100), #b datetime, #c datetime'
exec sp_executesql #q, #ParamDefinition,#a = #param1,#b = #proc_dateStart, #cTableName = #proc_dateEnd
Please use CONVERT function
CAST('''+CONVERT(VARCHAR(108),#proc_dateStart)+''' AS DATE) AND CAST('''+CONVERT(VARCHAR(108),#proc_dateEnd)+''' AS DATE)'

Cursorfetch:The number of variables declared in the INTO list must match that of selected columns

declare #id int
declare #empid int
set #id = 0
declare #schedindate datetime
declare #ss nvarchar(100)
declare #indice nvarchar(2)
declare #FromDate datetime
declare #ToDate datetime
declare #TimeInR datetime
declare #TimeOutR datetime
set #FromDate = '2009-01-14'
set #ToDate = '2010-01-30'
Declare cc cursor for select distinct empid from ta_timecard where schedindate between #FromDate and #ToDate
open cc
fetch next from cc into #empid
while (##fetch_status = 0)
begin
set #id = #id + 1
insert into ta_MonthlyAttendance (ID, EmpID) values (#id, #empid)
declare cc2 cursor for select distinct schedindate, TimeInR, TimeOutR from ta_timecard where empid = #empid and schedindate between #FromDate and #ToDate
open cc2
fetch next from cc2 into #schedindate, #TimeInR
while (##fetch_status = 0)
begin
set #indice = cast(datediff(day, #fromdate, #schedindate) as nvarchar(4))
set #TimeInR = (select TOP 1 ta_TimeCard.TimeInR from ta_TimeCard where (#schedindate between #FromDate and #ToDate) and EmpID=#empid)
set #schedindate = (select TOP 1 ta_TimeCard.SchedInDate from ta_TimeCard where (#schedindate between #FromDate and #ToDate) and empid=#empid)
set #ss = 'update ta_MonthlyAttendance set NOD ' + #indice + ' = + dbo.ta_dayofweek('+ char(39) + convert(nvarchar(50), #schedindate, 102) + char(39) +' ) , TimeInR ' + #indice + ' = + #TimeInR + where empid = ' + cast(#empid as nvarchar(20))
execute sp_executesql #ss
fetch next from cc2 into #schedindate, #TimeInR
end
close cc2
deallocate cc2
fetch next from cc into #empid
end
close cc
Deallocate cc
this code gives error in the line "fetch next from cc2 into #schedindate, #TimeInR"
where's my fault? I can't find it..
declare cc2 cursor for
select distinct schedindate, TimeInR, TimeOutR
from ta_timecard where empid = #empid
and schedindate between #FromDate and #ToDate
open cc2
fetch next from cc2 into #schedindate, #TimeInR
You are selecting schedindate, TimeInR, TimeOutR but the into statement has only #schedindate, #TimeInR
Try this one -
DECLARE
#empid INT
, #schedindate DATETIME
, #ss NVARCHAR(100)
, #indice NVARCHAR(2)
, #FromDate DATETIME
, #ToDate DATETIME
, #TimeInR DATETIME
, #TimeOutR DATETIME
SELECT
#FromDate = '20090114'
, #ToDate = '20100130'
DECLARE #temp TABLE
(
schedindate DATETIME
, TimeInR VARCHAR(10)
, TimeOutR VARCHAR(10)
, empid INT
)
INSERT INTO #temp (schedindate, TimeInR, TimeOutR, empid)
SELECT DISTINCT
schedindate
, TimeInR
, TimeOutR
, empid
FROM dbo.ta_timecard
WHERE schedindate BETWEEN #FromDate AND #ToDate
DECLARE #ids TABLE(id BIGINT IDENTITY(1,1), emp BIGINT)
INSERT INTO #ids (emp)
SELECT DISTINCT empid
FROM #temp
INSERT INTO dbo.ta_MonthlyAttendance(id, EmpID)
SELECT id, emp
FROM #ids
DECLARE cc CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT DISTINCT empid
FROM #temp
OPEN cc
FETCH NEXT FROM cc INTO #empid
WHILE (##fetch_status = 0) BEGIN
SELECT
#indice = CAST(DATEDIFF(DAY, #fromdate, t.SchedInDate) AS NVARCHAR(4))
, #TimeInR = t.TimeInR
, #schedindate = t.SchedInDate
FROM #temp t
WHERE empid = #empid
SELECT #ss = 'update ta_MonthlyAttendance set NOD ' + #indice
+ ' = + dbo.ta_dayofweek(' + CHAR(39)
+ CONVERT(NVARCHAR(50), #schedindate, 102) + CHAR(39) + ' ) , TimeInR '
+ #indice + ' = ' + #TimeInR + ' where empid = ' + CAST(#empid AS NVARCHAR(20))
EXEC sys.sp_executesql #ss
FETCH NEXT FROM cc INTO #empid
END
CLOSE cc
DEALLOCATE cc

Invalid object name 'table1'

DECLARE
#empid INT
, #schedindate DATETIME
, #ss NVARCHAR(100)
, #indice NVARCHAR(3)
, #FromDate DATETIME
, #ToDate DATETIME
, #TimeInR NVARCHAR(20)
, #TimeOutR DATETIME,#day nvarchar(3)
SELECT
#FromDate = '20090114'
, #ToDate = '20100130'
DECLARE #temp TABLE
(
schedindate DATETIME
, TimeInR VARCHAR(10)
, TimeOutR VARCHAR(10)
, empid INT
)
delete from PayrollTEST.dbo.[table1]
INSERT INTO #temp (schedindate, TimeInR, TimeOutR, empid)
SELECT DISTINCT
schedindate
, TimeInR
, TimeOutR
, empid
FROM dbo.ta_timecard
WHERE schedindate BETWEEN #FromDate AND #ToDate
DECLARE #ids TABLE(id BIGINT IDENTITY(1,1), emp BIGINT)
INSERT INTO #ids (emp)
SELECT DISTINCT empid
FROM #temp
INSERT INTO PayrollTEST.dbo.[table1](id, EmpID)
SELECT id, emp
FROM #ids
DECLARE cc CURSOR LOCAL FAST_FORWARD READ_ONLY FOR
SELECT DISTINCT empid
FROM #temp
OPEN cc
FETCH NEXT FROM cc INTO #empid
WHILE (##fetch_status = 0) BEGIN
SELECT
#indice = (select DATEDIFF(day,#fromdate, t.SchedInDate))
--, #TimeInR = t.TimeInR
, #schedindate = t.SchedInDate
, #day = dbo.ta_dayofweek(#schedindate)
FROM #temp t
WHERE empid = #empid
print(#indice)
print(#day)
print(#schedindate)
print(#TimeInR)
-- SELECT #ss = 'update table1 set nod' + #indice
-- + ' = '+ convert(nvarchar(3),#day) +' , din'
-- + #indice + ' = ' + #Schedindate + ' where empid = ' + CAST(#empid AS NVARCHAR(20))
SELECT #ss = 'update table1 set nod' + #indice
+ ' = '+ convert(nvarchar(3),#day) + ' where empid = ' + CAST(#empid AS NVARCHAR(20))
EXEC master.dbo.sp_executesql #ss
FETCH NEXT FROM cc INTO #empid
END
CLOSE cc
DEALLOCATE cc
Why am I getting this error? i'm in the right database and the table exist. I appreciate any help
Did you make sure that you are in the right database ?
you can run SELECT DB_NAME() to see your current databse