MSSQL After Insert Trigger not executing after database restore - sql

I restored a SQL 2k5 Database to a SQL 2014 server (Note this is a SQL Web Edition instance) and it does not seem to execute at all.
CREATE TRIGGER [dbo].[tInsertTransactionsSnapshot]
ON [GDL_TNA].[dbo].[TRANSACTIONS]
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #FirstRecord int
DECLARE #LastRecord int
DECLARE #MSTSQ int
DECLARE #EventDate varchar(50)
SET #FirstRecord = (SELECT TOP 1 T_ID FROM INSERTED ORDER BY T_ID ASC)
SET #LastRecord = (SELECT TOP 1 T_ID FROM INSERTED ORDER BY T_ID DESC)
insert into GDL_TNA.dbo.dbg(Dbgfirst,dbgLast) VALUES (#FirstRecord,#LastRecord)
WHILE #FirstRecord <= #LastRecord
BEGIN
SET #MSTSQ = (SELECT MST_SQ FROM INSERTED WHERE T_ID = #FirstRecord)
SET #EventDate = (SELECT T_Date FROM INSERTED WHERE T_ID = #FirstRecord)
IF EXISTS(SELECT NULL FROM GDL_TNA.dbo.SNAPSHOTs WHERE MST_SQ = #MSTSQ AND SS_EVENT_DATE = #EventDate AND SS_ACTIVE = 1 AND SS_TYPE = 'TRANSACTION')
BEGIN
UPDATE GDL_TNA.dbo.SNAPSHOTs SET SS_ACTIVE = 0 WHERE MST_SQ = #MSTSQ AND SS_EVENT_DATE = #EventDate AND SS_ACTIVE = 1 AND SS_TYPE = 'TRANSACTION'
END
INSERT INTO GDL_TNA.dbo.SNAPSHOTs
(
[SS_TYPE]
,[SS_EVENT]
,[MST_SQ]
,[MD_ACTIVE]
,[MST_FIRST_NAME]
,[MST_LAST_NAME]
,[MD_SHIFTSTART]
,[MD_SHIFTEND]
,[COMP_ID]
,[DEPT_ID]
,[FUNC_ID]
,[MST_PREVIOUS_FIRST_NAME]
,[MST_PREVIOUS_LAST_NAME]
,[MST_RATE_NORMAL]
,[MST_RATE_TIMEANDHALF]
,[MST_RATE_DOUBLE]
,[MST_RATE_SPECIAL]
,[SS_EVENT_ID]
,[SS_EVENT_DATE]
,[SS_EVENT_START]
,[SS_EVENT_END]
,[SS_EVENT_APPROVED]
,[SS_EVENT_RATETYPE]
)
SELECT
'TRANSACTION'
,'INSERT'
,MST_SQ
,MD_ACTIVE
,MST_FIRST_NAME
,MST_LAST_NAME
,MD_SHIFTSTART
,MD_SHIFTEND
,COMP_ID
,DEPT_ID
,FUNC_ID
,MST_PREVIOUS_FIRST_NAME
,MST_PREVIOUS_LAST_NAME
,MST_RATE_NORMAL
,MST_RATE_TIMEANDHALF
,MST_RATE_DOUBLE
,MST_RATE_SPECIAL
,(
SELECT T_ID
FROM INSERTED
WHERE T_ID = #FirstRecord
)
,(
SELECT T_Date
FROM INSERTED
WHERE T_ID = #FirstRecord
)
,ISNULL((
SELECT
CASE
WHEN len(T_TIMEIN) = 6 THEN left(T_TIMEIN,2) + ':' + right(left(T_TIMEIN,4),2) + ':' + right(T_TIMEIN,2) + '.000'
WHEN len(T_TIMEIN) < 6 THEN '0'+left(T_TIMEIN,1) + ':' + right(left(T_TIMEIN,3),2) + ':' + right(T_TIMEIN,2) + '.000'
END
FROM INSERTED
WHERE T_ID = #FirstRecord
),'00:00:00.000')
,ISNULL((
SELECT
CASE
WHEN len(T_TIMEOUT) = 6 THEN left(T_TIMEOUT,2) + ':' + right(left(T_TIMEOUT,4),2) + ':' + right(T_TIMEOUT,2) + '.000'
WHEN len(T_TIMEOUT) < 6 THEN '0'+left(T_TIMEOUT,1) + ':' + right(left(T_TIMEOUT,3),2) + ':' + right(T_TIMEOUT,2) + '.000'
END
FROM INSERTED
WHERE T_ID = #FirstRecord
),'00:00:00.000')
,1
,1
FROM GDL_TNA.dbo.MASTER_DETAILS
WHERE MST_SQ = #MSTSQ
SET #FirstRecord = #FirstRecord + 1
END
END
Steps I have Taken
Check Trigger Status: SELECT name, is_disabled FROM sys.triggers (All Enabled)
Drop & Recreate Triggers on 2014 instance
Ran a Recompile of table with sp_recompile
Any advice would be greatly appreciated.

Related

Updating SQL Server based on unique row using WHILE LOOP

I'm trying to update my table using WHILE LOOP, unfortunately, instead of updating it based on employeeidno, it gathers all the total aremployee in all employeeidno and then update the row of all employeeidno based on it.
Is there a way to segregate the SET #aremployee based on employeeidno?
What I basically what for this query is that for every WHILE LOOP it will capture the data gathered, and then add it to the next loop, but is based on employeeidno.
DECLARE #cnt INT = 0;
DECLARE #aremployee FLOAT = 0;
WHILE #cnt <= (SELECT TOP 1 RIGHT(accountcode,2) FROM accounting_tblearningsamendmentaccount_db WHERE LEFT(accountcode,2) = '02' AND approvedby IS NOT NULL ORDER BY accountcode DESC)
BEGIN
SET #cnt = #cnt + 1;
UPDATE accounting_tblpayroll_db
SET #aremployee = #aremployee + x.aremployee,
accounting_tblpayroll_db.aremployee = #aremployee
FROM (SELECT
MAX(RTRIM(LTRIM(employeeidno))) AS 'employeeidno',
SUM(debit) AS 'aremployee',
MAX(accountcode) as 'accountcode',
MAX(RTRIM(LTRIM(referenceno))) AS 'referenceno',
MAX(RTRIM(LTRIM(particulars))) AS 'particulars',
MAX(RTRIM(LTRIM(postedby))) AS 'postedby',
MAX(RTRIM(LTRIM(approvedby))) AS 'approvedby',
MAX(RTRIM(LTRIM(notedby))) AS 'notedby'
FROM accounting_tblearningsamendment_db WHERE LEFT(accountcode,2) = LEFT('02000',2)
AND accountcode != '02001' AND accountcode != '02002'
AND payrolldue is null AND datedue BETWEEN '2020-10-06' AND '2020-10-20'
AND accountcode = CONCAT('020', CONCAT(CASE WHEN #cnt < 10 THEN '0' ELSE '' END , #cnt))
GROUP BY employeeidno) AS x
WHERE x.employeeidno = accounting_tblpayroll_db.employeeidno
AND x.aremployee <
(((accounting_tblpayroll_db.cutoffpay + accounting_tblpayroll_db.leave + accounting_tblpayroll_db.nightdifferential + accounting_tblpayroll_db.regularholiday + accounting_tblpayroll_db.specialholiday + accounting_tblpayroll_db.additionalincome + accounting_tblpayroll_db.overtime
+ accounting_tblpayroll_db.apemployee + accounting_tblpayroll_db.thmonth + accounting_tblpayroll_db.christmasbonus + accounting_tblpayroll_db.administrativeallowance + accounting_tblpayroll_db.supervisoryallowance
+ accounting_tblpayroll_db.hazardallowance + accounting_tblpayroll_db.shortageallowance + accounting_tblpayroll_db.licenseallowance + accounting_tblpayroll_db.transportationallowance + loyaltyincentiveallowance - '1000.00'
)
- (accounting_tblpayroll_db.sss_ee + accounting_tblpayroll_db.med_ee + accounting_tblpayroll_db.pagibig_ee + accounting_tblpayroll_db.late + accounting_tblpayroll_db.undertime)))
AND accounting_tblpayroll_db.datefrom = '2020-10-06'
AND accounting_tblpayroll_db.dateto = '2020-10-20';
END;
Thank you in advance.
Edit:
This is the simplified version:
DROP TABLE #temtable1;
DROP TABLE #temtable2;
CREATE TABLE #temtable1
(
referenceno int,
employeeid varchar(10),
ccode varchar(10),
amount float(10)
);
INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1001','2001','3001','11000.00');
INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1003','2002','3002','11000.00');
INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1005','2003','3003','11000.00');
INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1001','2001','3004','10000.00');
INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1003','2002','3005','10000.00');
INSERT INTO #temtable1
(referenceno,employeeid,ccode,amount)
VALUES('1005','2003','3006','10000.00');
CREATE TABLE #temtable2
(
referenceno int,
employeeid varchar(10),
total float(10)
);
INSERT INTO #temtable2
(referenceno,employeeid,total)
VALUES('1001','2001',NULL);
INSERT INTO #temtable2
(referenceno,employeeid,total)
VALUES('1002','2002',NULL);
INSERT INTO #temtable2
(referenceno,employeeid,total)
VALUES('1003','2003',NULL);
DECLARE #cnt INT = 0;
DECLARE #total INT = 0;
WHILE #cnt <= 10
BEGIN
SET #cnt = #cnt + 1;
UPDATE #temtable2
SET #total = #total + x1.amount,
total = #total
FROM(SELECT
MAX(referenceno) as referenceno,
MAX(employeeid) as employeeid,
ccode as ccode,
SUM(amount) as amount
FROM #temtable1
WHERE
ccode = CONCAT('30', CONCAT(CASE WHEN #cnt < 10 THEN '0' ELSE '' END , #cnt))
GROUP BY
employeeid,ccode) AS x1
WHERE x1.employeeid = #temtable2.employeeid
AND x1.amount < 25000
END
select * from #temtable2
Current Result:
Expected Result:
What I intend for this is that the query will loop and add all code that starts with 3, depending on what employeeid the data is under.
The query will the first loop starting 3001, then up to 3010, and add it consecutively until it will not exceed 25000, but it's on every employeeid.

Returning last result set from stored procedure

Stored procedure a is calling another procedure b and b has two out parameter and also a result set with select statement. Now I want to return result set from a with select statement but when I execute a it shows two result sets, first from b and then from a.
So how to get result set of just a? Please I don't want to store result of b into temp table. thanks.
a usp_Save_IssuancePcsStToSt
b usp_Stitcher_Stock_Form
details of b
#st_code smallint,
#QltyCode varchar(30),
#ColorCode varchar(6),
#NetPieces int = NULL out ,
#NetWeight numeric(13,4) = NULL out
)
AS
BEGIN
DECLARE #rowNum int= 0;
SELECT
#rowNum = ROW_NUMBER() OVER (ORDER BY st_code, quality_code, o_color_code),
#NetPieces = ISNULL(SUM((rec_pcs + adj_plus_pcs + reopen_pcs)- (issued_pcs + adj_minus_pcs + re_packing_pcs+ return_pcs)), 0),
#NetWeight = ISNULL(SUM((rec_wt + adj_plus_wt + reopen_wt) - (issued_wt + adj_minus_wt + return_wt + re_packing_wt)), 0.00)
FROM
dbo.v_rpt_cc_transaction_all
WHERE
doc_date >= '03/02/2014'
AND st_code = #st_code
AND quality_code = #QltyCode
AND o_color_code = #ColorCode
GROUP BY
st_code, quality_code, o_color_code
SELECT #rowNum AS SerialNumber, ISNULL(#NetPieces, 0) AS net_pcs , ISNULL(#NetWeight, 0.00) AS net_wt

Grouping within a While Loop, SQL Server

I've been building a while loop to populate a lot of data, and I'm struggling with grouping within the query - I want to add a group on Membership_Level but each time it is returning identical values (the total) for each Level.
Can anyone help me?
Thank you in advance!!!
DECLARE #Counter int
DECLARE #NumPerson int
SET #Counter = 1
WHILE #Counter <= 12
BEGIN
SET #NumPerson = (SELECT
SUM(Amount)
FROM [NewMember]
WHERE LEFT([PERIOD], 4) = 2016
AND GRADE_STATUS = 'N'
AND RIGHT([Period], 2) = #Counter)
SELECT
*
FROM (SELECT
CAST(#NumPerson AS varchar(6)) AS 'Number',
CASE
WHEN LEN(CAST(#Counter AS varchar(2))) = 1 THEN '0' + CAST(#Counter AS varchar(2))
ELSE CAST(#Counter AS varchar(2))
END AS 'Month') s
JOIN (SELECT
MAX('1') AS NGroup,
[PERIOD],
RIGHT([Period], 2) AS 'Month',
MEMBERSHIP_LEVEL
FROM [NewMember]
WHERE LEFT([PERIOD], 4) = 2016
AND GRADE_STATUS = 'N'
GROUP BY [MEMBERSHIP_LEVEL],
[PERIOD],
RIGHT([Period], 2)) t
ON s.[Month] = t.[Month]
SET #Counter = #Counter + 1
END

SQL Server 2008 Audit trigger based on sub string

I would like to create a trigger based on a column but only for those records that end in _ess. How can I set up an audit trigger to do this?
Here is the current trigger but it just checks for all changes to username, whereas I just want it to check when username is updated to or from a username ending in _ess.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[AUDIT_UPD_HRPERSONS_USERNAME] ON [dbo].[HRPersons] FOR UPDATE NOT FOR REPLICATION As
BEGIN
DECLARE
#OperationNum int,
#DBMSTransaction VARCHAR(255),
#OSUSER VARCHAR(50),
#DBMSUSER VARCHAR(50),
#HostPhysicalAddress VARCHAR(17),
#contexto varchar(128),
#ApplicationModifierUser varchar(50),
#SessionInfo_OSUser varchar(50),
#HostLogicalAddress varchar(30)
Set NOCOUNT On
IF ##trancount>0
BEGIN
EXECUTE sp_getbindtoken #DBMSTransaction OUTPUT
END
ELSE BEGIN
SET #DBMSTransaction = NULL
END
IF PatIndex( '%\%',SUSER_SNAME()) > 0
BEGIN
set #OSUSER = SUSER_SNAME()
set #DBMSUSER = NULL
END
ELSE BEGIN
SET #OSUSER = NULL
SET #DBMSUSER = SUSER_SNAME()
END
set #HostPhysicalAddress = (SELECT net_address FROM master..sysprocesses where spid=##spid )
set #HostPhysicalAddress = substring (#HostPhysicalAddress,1,2) + '-' + substring (#HostPhysicalAddress,3,2) + '-' + substring (#HostPhysicalAddress,5,2) + '-' + substring (#HostPhysicalAddress,7,2) + '-' + substring (#HostPhysicalAddress,9,2) + '-' + substring (#HostPhysicalAddress,11,2)
SELECT #contexto=CAST(context_info AS varchar(128)) FROM master..sysprocesses WHERE spid=##SPID
IF (PatIndex( '%APPLICATION_USER=%',#contexto) is not null) and (PatIndex( '%APPLICATION_USER=%',#contexto) > 0)
set #ApplicationModifierUser=substring(ltrim(substring(#contexto,PatIndex( '%APPLICATION_USER=%',#contexto)+17,128)),1, charIndex( '///',ltrim(substring(#contexto,PatIndex( '%APPLICATION_USER=%',#contexto)+17,128) ) ) - 1 )
ELSE
set #ApplicationModifierUser=NULL
IF (PatIndex( '%OS_USER=%',#contexto) is not null) and ( PatIndex( '%OS_USER=%',#contexto)>0 )
set #SessionInfo_OSUser=substring(ltrim(substring(#contexto,PatIndex( '%OS_USER=%',#contexto)+8,128)),1, charIndex( '///',ltrim(substring(#contexto,PatIndex( '%OS_USER=%',#contexto)+8,128) ) ) - 1 )
ELSE
set #SessionInfo_OSUser=NULL
IF (PatIndex( '%LOGICAL_ADDRESS=%',#contexto) is not null) and (PatIndex( '%LOGICAL_ADDRESS=%',#contexto)>0)
set #HostLogicalAddress=substring(ltrim(substring(#contexto,PatIndex( '%LOGICAL_ADDRESS=%',#contexto)+16,128)),1, charIndex( '///',ltrim(substring(#contexto,PatIndex( '%LOGICAL_ADDRESS=%',#contexto)+16,128) ) ) - 1 )
ELSE
set #HostLogicalAddress=NULL
INSERT INTO AuditedOperations ( Application, Object, OperationType, ModifiedDate, ApplicationModifierUser, OSModifierUser, DBMSModifierUser, Host, HostLogicalAddress, HostPhysicalAddress, DBMSTransaction)
VALUES (APP_NAME(), 'HRPERSONS', 'U', GETDATE(), #ApplicationModifierUser, #OSUSER, #DBMSUSER, HOST_NAME(), #HostLogicalAddress, #HostPhysicalAddress, #DBMSTransaction)
Set #OperationNum = ##IDENTITY
INSERT INTO AuditedRows (OperationNum, RowPK)
SELECT #OperationNum, ISNULL(CAST(INSERTED.ID as nvarchar),CAST(DELETED.ID as nvarchar))
FROM INSERTED FULL OUTER JOIN DELETED ON INSERTED.ID=DELETED.ID
INSERT INTO AuditedRowsColumns (OperationNum, RowPK, ColumnName, ColumnAudReg, OldValue, NewValue)
SELECT #OperationNum, ISNULL(CAST(INSERTED.ID as nvarchar),CAST(DELETED.ID as nvarchar)), 'USERNAME','A', CONVERT( VARCHAR(3500),DELETED.USERNAME), CONVERT( VARCHAR(3500),INSERTED.USERNAME)
FROM INSERTED FULL OUTER JOIN DELETED ON INSERTED.ID=DELETED.ID
END
GO
Just add this:
INSERT INTO AuditedRows (OperationNum, RowPK)
SELECT #OperationNum, ISNULL(CAST(INSERTED.ID as nvarchar),CAST(DELETED.ID as nvarchar))
FROM INSERTED FULL OUTER JOIN DELETED ON INSERTED.ID=DELETED.ID
-- Restrict it to only those where the username is changing from or to %_ess
WHERE (deleted.username like '%_ess' or inserted.username like '%_ess')
INSERT INTO AuditedRowsColumns (OperationNum, RowPK, ColumnName, ColumnAudReg, OldValue, NewValue)
SELECT #OperationNum, ISNULL(CAST(INSERTED.ID as nvarchar),CAST(DELETED.ID as nvarchar)), 'USERNAME','A', CONVERT( VARCHAR(3500),DELETED.USERNAME), CONVERT( VARCHAR(3500),INSERTED.USERNAME)
FROM INSERTED FULL OUTER JOIN DELETED ON INSERTED.ID=DELETED.ID
-- Restrict it to only those where the username is changing from or to %_ess
WHERE (deleted.username like '%_ess' or inserted.username like '%_ess')

How to get rows having sum equal to given value

There is table contain
ID Qty
----------
1 2
2 4
3 1
4 5
Now if i had to choose rows where sum of Qty equals to 10,
How can i do this ?
like 2+4+1 = 7
but if i add 5 then 12
so ignore 2, then
4+1+5 = 10
How can i achieve this ?
Edit:
I want any possible combination which sums up to gives value.
suppose 7 then any rows which sums up to 7
like wise if 8 then any rows sums up to 8
want row/rows having combination equals to given value.
The problem you want to solve is called the subset sum problem. Unfortunately, it is NP-complete.
This means that, whether you use SQL or any other language to solve it, you will only be able to solve very small instances of the problem, i.e. ones with only a few entries in the table. Otherwise, the runtime will become excessive, since it grows exponentially with the number of rows in the table. The reason for this is that there is essentially no better way of finding the solution than to try all possible combinations.
If an approximate solution is acceptable, there is a polynomial time algorithm, which is described on the Wikipedia page.
If you want it to be exactly always three numbers that add to 10, then this
SELECT
*
FROM
MyTable t1
JOIN
MyTable t2 ON t1.ID <> t2.ID
JOIN
MyTable t3 ON t1.ID <> t3.ID AND t2.ID <> t3.ID
WHERE
t1.Qty + t2.Qty + t3.Qty = 10
If you want 2 or 4 or 5 numbers then you can't really do it in SQL
Edit:
Updated to ignore by ID not Qty
And again: If you want 2 or 4 or 5 numbers then you can't really do it in SQL
When you are dealing with such task in SQL you need to go to the cursors approach.
Cursors let you perform row by row operations and that's what you need, for example:
You want to make groups of where the summed quantity is 10
This are the tasks
select all the table into a temp table #TBL_ALL
loop row by row and when the rows sum up 10, delete from the temp table and insert into a final temp table #TBL_FINAL
do this until the #TBL_ALL sum cant be performed
An example:
Test table:
/****** Object: Table [dbo].[tblExample] Script Date: 06/09/2011 11:25:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[tblExample](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Qty] [int] NOT NULL,
CONSTRAINT [PK_tblExample] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Test Data:
INSERT INTO tblExample SELECT 2;
INSERT INTO tblExample SELECT 4;
INSERT INTO tblExample SELECT 1;
INSERT INTO tblExample SELECT 5;
INSERT INTO tblExample SELECT 5;
INSERT INTO tblExample SELECT 11;
INSERT INTO tblExample SELECT 1;
INSERT INTO tblExample SELECT 2;
INSERT INTO tblExample SELECT 3;
INSERT INTO tblExample SELECT 4;
INSERT INTO tblExample SELECT 7;
INSERT INTO tblExample SELECT 9;
INSERT INTO tblExample SELECT 1;
INSERT INTO tblExample SELECT 2;
Store procedure:
http://pastebin.com/EFeZcKXf
Results:
Grouped table:
ids qty group
12 9 1
7 1 1
11 7 2
9 3 2
4 5 3
5 5 3
2 4 4
10 4 4
14 2 4
Numbers not used:
id qty
1 2
8 2
3 1
13 1
6 11
Hope it helps
SP for those who cant access PasteBin
CREATE PROCEDURE getGroups
(
#groupByQty int, -- grouping number
#numberRuns int -- how many loops
-- usage: getGroups 10, 10
)
AS
SET NOCOUNT ON;
-- declare all variables
DECLARE #rowId int,
#rowQty int,
#rowTotal int,
#groupId int,
#totalRuns int,
#continue bit
-- set up our final temporary table
CREATE TABLE #TBL_COUNT
(
ids NVARCHAR(4000),
qty int,
[group] int
)
-- initializate variable
SET #groupId = 1;
SET #continue = 1;
SET #totalRuns = 0;
SELECT Id, Qty INTO #TBL_ALL FROM tblExample ORDER BY Qty DESC;
WHILE #totalRuns <= #numberRuns
BEGIN
-- declare the cursor
DECLARE Product CURSOR FOR SELECT Id, Qty FROM #TBL_ALL ORDER BY Qty DESC;
OPEN Product;
FETCH Product INTO #rowId, #rowQty;
PRINT ' ';
PRINT '### Run: ' + CAST(#totalRuns AS nvarchar(10)) + ' #################################################################';
PRINT 'Grouping Table by ' + CAST(#groupByQty AS nvarchar(10)) + ' | group id = ' + CAST(#groupId AS nvarchar(10));
-- Retrieve and process the first row
SELECT Top 1 #rowId = Id, #rowQty = Qty FROM #TBL_ALL ORDER BY Qty DESC;
PRINT 'First Row: id = ' + CAST(#rowId AS nvarchar(10)) + ' | qty = ' + CAST(#rowQty AS nvarchar(10));
-- sum it up and see if we have #groupByQty
SELECT #rowTotal = ISNULL(SUM(qty),0) FROM #TBL_COUNT WHERE [group] = #groupId;
PRINT 'Current sum in #TBL_COUNT: #groupId = '+ CAST(#groupId AS nvarchar(10)) +' | #rowTotal = ' + CAST(#rowTotal AS nvarchar(10)) + ' | (#rowTotal + #rowQty) = ' + CAST((#rowTotal + #rowQty) AS nvarchar(10));
IF #rowQty > #groupByQty
BEGIN
PRINT ' x First row has an unused number';
END
ELSE
BEGIN
-- handle result
IF (#rowTotal + #rowQty) = #groupByQty
BEGIN
PRINT '+++ Current sum is ' + CAST(#groupByQty AS nvarchar(10)) + ' +++';
-- save number
INSERT INTO #TBL_COUNT SELECT #rowId, #rowQty, #groupId;
PRINT '### Inserted final # into #TBL_COUNT : id = ' + CAST(#rowId AS nvarchar(10)) + ' | qty = ' + CAST(#rowQty AS nvarchar(10)) + ' | group = ' + CAST(#groupId AS nvarchar(10));
-- remove from table as we use it already
DELETE FROM #TBL_ALL WHERE Id = #rowId;
-- we got 10, let's change our Groupping
SET #groupId = (#groupId + 1);
PRINT 'New group id: ' + CAST(#groupId AS nvarchar(10));
END
ELSE
BEGIN
IF (#rowTotal + #rowQty) < #groupByQty
BEGIN
PRINT '### Inserted into #TBL_COUNT : id = ' + CAST(#rowId AS nvarchar(10)) + ' | qty = ' + CAST(#rowQty AS nvarchar(10)) + ' | group = ' + CAST(#groupId AS nvarchar(10));
-- save number
INSERT INTO #TBL_COUNT SELECT #rowId, #rowQty, #groupId;
-- remove from table as we use it already
DELETE FROM #TBL_ALL WHERE Id = #rowId;
END
ELSE
BEGIN
PRINT ' x Unmatch number, will handle this latter';
END
END
END
-- start the main processing loop
WHILE ##Fetch_Status = 0
BEGIN
FETCH Product INTO #rowId, #rowQty;
PRINT '##Fetch_Status = ' + CAST(##Fetch_Status AS nvarchar(100));
IF ##Fetch_Status < 0
BEGIN
BREAK
END
-- we have the values of our row, let's use them
PRINT 'Fetched Row: id = ' + CAST(#rowId AS nvarchar(10)) + ' | qty = ' + CAST(#rowQty AS nvarchar(10));
-- sum it up and see if we have #groupByQty
SELECT #rowTotal = ISNULL(SUM(qty),0) FROM #TBL_COUNT WHERE [group] = #groupId;
PRINT 'Current sum in #TBL_COUNT: #groupId = '+ CAST(#groupId AS nvarchar(10)) +' | #rowTotal = ' + CAST(#rowTotal AS nvarchar(10)) + ' | (#rowTotal + #rowQty) = ' + CAST((#rowTotal + #rowQty) AS nvarchar(10));
-- handle result
IF (#rowTotal + #rowQty) = #groupByQty
BEGIN
PRINT '+++ Current sum is ' + CAST(#groupByQty AS nvarchar(10)) + ' +++';
-- save number
INSERT INTO #TBL_COUNT SELECT #rowId, #rowQty, #groupId;
PRINT '### Inserted final # into #TBL_COUNT : id = ' + CAST(#rowId AS nvarchar(10)) + ' | qty = ' + CAST(#rowQty AS nvarchar(10)) + ' | group = ' + CAST(#groupId AS nvarchar(10));
-- remove from table as we use it already
DELETE FROM #TBL_ALL WHERE Id = #rowId;
-- we got 10, let's change our Groupping
SET #groupId = (#groupId + 1);
PRINT 'New group id: ' + CAST(#groupId AS nvarchar(10));
-- start again
BREAK;
END
ELSE
BEGIN
IF (#rowTotal + #rowQty) < #groupByQty
BEGIN
PRINT '### Inserted into #TBL_COUNT : id = ' + CAST(#rowId AS nvarchar(10)) + ' | qty = ' + CAST(#rowQty AS nvarchar(10)) + ' | group = ' + CAST(#groupId AS nvarchar(10));
-- save number
INSERT INTO #TBL_COUNT SELECT #rowId, #rowQty, #groupId;
-- remove from table as we use it already
DELETE FROM #TBL_ALL WHERE Id = #rowId;
END
ELSE
BEGIN
PRINT ' x Unmatch number, will handle this latter';
END
END
END -- END WHILE ##Fetch_Status = 0
SET #totalRuns = #totalRuns + 1;
-- Close and dealocate
CLOSE Product;
DEALLOCATE Product;
END -- END WHILE totalRuns <= #numberRuns
-- let's sum our last group and remove it if it's not #groupByQty
SELECT #rowTotal = ISNULL(SUM(qty),0) FROM #TBL_COUNT WHERE [group] = #groupId;
IF #rowTotal <> #groupByQty
BEGIN
SET IDENTITY_INSERT #TBL_ALL ON
INSERT INTO #TBL_ALL (Id, Qty) SELECT Ids, Qty FROM #TBL_COUNT WHERE [group] = #groupId;
DELETE FROM #TBL_COUNT WHERE [group] = #groupId;
END
SET NOCOUNT OFF;
-- Show and Delete temp tables
SELECT * FROM #TBL_COUNT;
SELECT * FROM #TBL_ALL;
DROP TABLE #TBL_COUNT;
DROP TABLE #TBL_ALL;
P.S. I'm not a SQL Professional, so bear with me if I did something weird, and keep in mind that this is a performance waste, maybe someone can use the the Loop without Cursors, more in this page
If u add always 3 numbers its like gbn said, if not then u have to check every combination of ur rows which gives u 2 to the number_of_rows power cobinations and i dont see how can it be done on sql in one query. If u use loop in sql sure its possible but u should find some good algorithm to finish this task.