SQL Server stored procedure breaking up results - sql

I am trying to get a list back from a stored procedure, but I believe I may have used the wrong method?
The data I am getting back is fine, but is breaking up the results into sections instead of one continuous result.
I need it to be in one continuous result as it needs to be then exported out to an accounting program.
UPDATE
I maybe should have mentioned I am teaching myself SQL and procedures, so I don't entirely know what I am doing, so please forgive me. :)
I spent most of last week writing and re-writing before finally coming here to ask for help.
What I had written was overly complicated I now realise (not to mention not giving the response the way I needed.) I was trying to repurpose code I had found elsewhere.
This is my corrected code.
#varBillingDealerPeriodID int
AS
DECLARE #BillingDealerBatchRosterID int;
BEGIN TRY
SELECT count( * ) AS ItemTotalCount
, di.DealerName
, di.DealerID
, bdbr.BillingDateTo
, bdinr.BillingDealerInvoiceNumber
FROM dbo.billing_dealer_batch_item bdbi
LEFT JOIN dbo.dealer_info di ON di.DealerID = bdbi.DealerID
LEFT JOIN dbo.billing_dealer_batch_roster bdbr ON bdbr.BillingDealerBatchRosterID = bdbi.BillingDealerBatchRosterID
LEFT JOIN dbo.billing_dealer_invoice_number_roster bdinr ON bdinr.DealerID = di.DealerID
WHERE bdbi.BillingDealerBatchRosterID IN (
SELECT DISTINCT BillingDealerBatchRosterID
FROM dbo.billing_dealer_batch_roster
WHERE BillingDealerPeriodID = #varBillingDealerPeriodID
)
AND bdbi.ItemConditionID < 2
GROUP BY di.DealerName
, di.DealerID
, bdbr.BillingDateTo
, bdinr.BillingDealerInvoiceNumber
END TRY
Thank you for everyone's help!

Get rid of the cursor and the loop.
Then change this
AND bdbi.BillingDealerBatchRosterID = #BillingDealerBatchRosterID
To this
AND bdbi.BillingDealerBatchRosterID IN (
SELECT DISTINCT BillingDealerBatchRosterID
FROM dbo.billing_dealer_batch_roster
WHERE BillingDealerPeriodID = #varBillingDealerPeriodID
)

By using the cursor you can just use the following codes. Here, you may need to change the data type for the temp table as per your need.
CREATE PROCEDURE [dbo].[billing_generate_invoice]
#varBillingDealerPeriodID int
AS
BEGIN
IF OBJECT_ID('tempdb..##tmp_billing_generate_invoice', 'U') IS NOT NULL
BEGIN
DROP TABLE ##tmp_billing_generate_invoice
END
CREATE TABLE ##tmp_billing_generate_invoice
(
ItemTotalCount INT,
BillingDealerBatchRosterID INT,
DealerName VARCHAR(500),
ServiceLevelID INT,
FreshItemFeeID INT,
WebsiteFeeID INT,
WebsiteBillingFrequencyID INT,
BillingDateTo DATE,
BillingDealerInvoiceNumber VARCHAR(500)
)
DECLARE #BillingDealerBatchRosterID int;
DECLARE MyCursor CURSOR LOCAL FOR
SELECT BillingDealerBatchRosterID
FROM dbo.billing_dealer_batch_roster
WHERE BillingDealerPeriodID = #varBillingDealerPeriodID;
OPEN MyCursor;
FETCH NEXT FROM MyCursor INTO #BillingDealerBatchRosterID;
WHILE ##fetch_status = 0
BEGIN
-- START
INSERT INTO ##tmp_billing_generate_invoice(
ItemTotalCount,
BillingDealerBatchRosterID,
DealerName,
ServiceLevelID,
FreshItemFeeID,
WebsiteFeeID,
WebsiteBillingFrequencyID,
BillingDateTo,
BillingDealerInvoiceNumber
)
SELECT
COUNT(*) AS ItemTotalCount,
bdbr.BillingDealerBatchRosterID,
di.DealerName,
-- di.DealerID
da.ServiceLevelID,
da.FreshItemFeeID,
da.WebsiteFeeID,
da.WebsiteBillingFrequencyID,
bdbr.BillingDateTo,
bdinr.BillingDealerInvoiceNumber
FROM
dbo.billing_dealer_batch_item bdbi
LEFT JOIN
dbo.dealer_info di ON di.DealerID = bdbi.DealerID
LEFT JOIN
dbo.dealer_account da ON da.DealerID = di.DealerID
LEFT JOIN
dbo.billing_dealer_batch_roster bdbr ON bdbr.BillingDealerBatchRosterID = bdbi.BillingDealerBatchRosterID
INNER JOIN
dbo.billing_dealer_invoice_number_roster bdinr ON bdinr.DealerID = di.DealerID
-- LEFT JOIN dbo.lookup__rate_weekly_fee_LR lrwf ON lrwf.ItemQuantity = ItemTotalCount
-- LEFT OUTER JOIN dbo.billing_dealer_batch bdb ON bdb.DealerID = di.DealerID
WHERE
bdbi.DealerID IN (SELECT DISTINCT DealerID
FROM dbo.billing_dealer_batch
WHERE DealerID = bdbi.DealerID
AND BillingDealerBatchRosterID = #BillingDealerBatchRosterID
AND DealerAccountStatusID = 4 -- Dealer Status 4 is ACTIVE only
)
AND bdbi.BillingDealerBatchRosterID = #BillingDealerBatchRosterID -- Roster Week
AND bdbi.ItemConditionID < 2 -- Less than 2 is AS-IS and Used
GROUP BY
bdinr.BillingDealerInvoiceNumber,
bdbi.DealerID,
di.DealerName,
-- di.DealerID
bdbr.BillingDateTo,
da.ServiceLevelID,
da.FreshItemFeeID,
da.WebsiteFeeID,
da.WebsiteBillingFrequencyID,
bdbr.BillingDealerBatchRosterID
ORDER BY
bdinr.BillingDealerInvoiceNumber;
-- END
FETCH NEXT FROM MyCursor INTO #BillingDealerBatchRosterID;
END;
CLOSE MyCursor;
DEALLOCATE MyCursor;
SELECT * FROM ##tmp_billing_generate_invoice
END

Related

Replacing Is Null Or Exist Inner Query Logic to Reduce Stored Procedure Execution Time

My stored procedure is currently using Is Null Or Exist logic combined with an inner query to filter out the records. The stored procedure is converting multiple comma-separated input values to temp tables (in the production scenario, the input record count will be much higher). And the inner query is using these temp tables for filter conditions. Due to the concern over query execution time would like to change the existing inner-query with an alternate (like left join). But need to retain the same Is Null Or Exist logic. Any suggestions?
DECLARE #SelectedOfferes varchar(1000) = 'FLT10,SPL20'
DECLARE #SelectedBrandCode varchar(1000) = '208,406'
DECLARE #CategoryCode varchar(1000) = 'GMOVN2,CELSMR,LCDTV38IN'
CREATE TABLE #SelectedOfferes
(
DiscountCode VARCHAR(20)
)
CREATE TABLE #BrandCode
(
BrandCode VARCHAR(20)
)
CREATE TABLE #CategoryCode
(
CategoryCode VARCHAR(20)
)
IF #SelectedOfferes IS NOT NULL
BEGIN
INSERT INTO #SelectedOfferes
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedOfferes, ',')
END
IF #SelectedBrandCode IS NOT NULL
BEGIN
INSERT INTO #BrandCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedBrandCode, ',')
END
IF #CategoryCode IS NOT NULL
BEGIN
INSERT INTO #CategoryCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#CategoryCode, ',')
END
SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode
WHERE (#SelectedOfferes IS NULL
OR (EXISTS (SELECT 1 FROM #SelectedOfferes OFR
WHERE OFR.DiscountCode = P.DiscountCode)))
AND (#SelectedBrandCode IS NULL
OR (EXISTS (SELECT 1 FROM #BrandCode BC
WHERE BC.BrandCode = P.BrandCode)))
AND (#CategoryCode IS NULL
OR (EXISTS (SELECT 1 FROM #CategoryCode CAT
WHERE CAT.CategoryCode = P.CategoryCode)))
Dynamic SQL version
I have some questions about your string split function, is it set-based or a looping query? If it's not set-based then you should probably replace it with Jeff Moden's DelimitedSplit8K available at http://www.sqlservercentral.com/articles/Tally+Table/72993/ .
The below example should work the same as what you supplied but should be faster since it removes the ORs and the correlated subqueries from the WHERE clause. I'm not a fan of using dynamic SQL but sometimes it is the best way to get the job done. Maybe someone else can come up with a non-dynamic solution that works as well or better.
DECLARE #SelectedOfferes varchar(1000) = 'FLT10,SPL20'
DECLARE #SelectedBrandCode varchar(1000) = '208,406'
DECLARE #CategoryCode varchar(1000) = 'GMOVN2,CELSMR,LCDTV38IN'
CREATE TABLE #SelectedOfferes
(
DiscountCode VARCHAR(20)
)
CREATE TABLE #BrandCode
(
BrandCode VARCHAR(20)
)
CREATE TABLE #CategoryCode
(
CategoryCode VARCHAR(20)
)
IF #SelectedOfferes IS NOT NULL
BEGIN
INSERT INTO #SelectedOfferes
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedOfferes, ',')
END
IF #SelectedBrandCode IS NOT NULL
BEGIN
INSERT INTO #BrandCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedBrandCode, ',')
END
IF #CategoryCode IS NOT NULL
BEGIN
INSERT INTO #CategoryCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#CategoryCode, ',')
END
DECLARE #SQL NVarchar(4000);
SET #SQL = N'SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode'
IF #SelectedOfferes IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #SelectedOfferes OFR ON OFR.DiscountCode = P.DiscountCode';
IF #SelectedBrandCode IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #BrandCode BC ON BC.BrandCode = P.BrandCode';
IF #CategoryCode IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #CategoryCode CAT ON CAT.CategoryCode = P.CategoryCode';
EXEC sys.sp_executesql #stmt = #SQL;
This method doesn't quite do what the OP wanted but is valid in many other cases
I have some questions about your string split function, is it set-based or a looping query? If it's not set-based then you should probably replace it with Jeff Moden's DelimitedSplit8K available at http://www.sqlservercentral.com/articles/Tally+Table/72993/ .
But either way the below change to your last query should help quite a bit. The IS NULL parts aren't needed since it is a LEFT JOIN and the table will be empty if the variable it is built with is NULL, so you get the same result with less work for the engine.
SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode
LEFT JOIN #SelectedOfferes OFR ON OFR.DiscountCode = P.DiscountCode
LEFT JOIN #BrandCode BC ON BC.BrandCode = P.BrandCode
LEFT JOIN #CategoryCode CAT ON CAT.CategoryCode = P.CategoryCode

In the Telerik Report Designer, how do you create a multi-column table with group headers?

I'm using the Telerik Report Designer (the standalone application, not the one in Visual Studio). I have a dataset with two fields: group and task. I'd like to make a table where each group is in it's own column with the tasks for that group listed below. The best I've come up with is a crosstab report that shows the groups and tasks and their counts, but this isn't what the client wants. How can I get the results I want in the report designer? If Telerik controls can't do this, how could I rewrite my SQL query to output the data is the format I want so I can directly use the SQL output to populate a table?
Here is my dataset:
The query I used to get that dataset is:
SELECT
tblDtl.Group
, tblDtl.Task
FROM tblHdr
INNER JOIN tblDtl ON tblHdr.CLHId = tblDtl.CLHId
INNER JOIN tblType ON tblHdr.CLHId = tblType.SelectedId
INNER JOIN tblOrder ON tblType.TypeId = tblOrder.Type
ORDER BY tblDtl.CLDDisplayOrder
Here is my desired output:
The best I've gotten is a crosstab that looks like this:
* Partial Answer *
I wasn't able to figure out how to get the 2 columns I wanted, but I used the code below to at least get the header in the first row with the details below it. I put this code in a stored procedure and then used that stored procedure as the data source for a table within the Telerik report.
CREATE TABLE #Checklist
(
Checklist varchar(200),
Notes varchar(50)
)
SET NOCOUNT ON;
DECLARE
#HeaderName varchar(200),
#GroupName varchar(200),
#TaskGroupName varchar(200),
#TaskDesc nvarchar(200)
DECLARE header_cursor CURSOR FOR
SELECT DISTINCT tblCheckListHdr.CLHName, tblCheckListDtl.CLDGroupName
FROM tblCheckListHdr
INNER JOIN tblCheckListDtl ON tblCheckListHdr.CLHId = tblCheckListDtl.CLHId
INNER JOIN tblServiceType ON tblCheckListHdr.CLHId = tblServiceType.SelectedCLHId
INNER JOIN tblWorkOrder ON tblServiceType.ServiceTypeId = tblWorkOrder.ServiceType
WHERE tblWorkOrder.WorkOrderId = #WOid
AND tblCheckListHdr.CLHActive = 1
ORDER BY tblCheckListDtl.CLDGroupName
OPEN header_cursor
FETCH NEXT FROM header_cursor INTO #HeaderName, #GroupName
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO #Checklist (Checklist, Notes)
SELECT #HeaderName + ' | ' + #GroupName, 'Y, N, NA, Notes' AS Notes
DECLARE detail_cursor CURSOR FOR
SELECT tblCheckListDtl.CLDGroupName
, tblCheckListDtl.CLDTaskDesc
FROM tblCheckListHdr
INNER JOIN tblCheckListDtl ON tblCheckListHdr.CLHId = tblCheckListDtl.CLHId
INNER JOIN tblServiceType ON tblCheckListHdr.CLHId = tblServiceType.SelectedCLHId
INNER JOIN tblWorkOrder ON tblServiceType.ServiceTypeId = tblWorkOrder.ServiceType
WHERE tblWorkOrder.WorkOrderId = #WOid
AND tblCheckListHdr.CLHActive = 1
AND tblCheckListDtl.CLDActive = 1
AND tblCheckListDtl.CLDGroupName = #GroupName
ORDER BY tblCheckListDtl.CLDDisplayOrder
OPEN detail_cursor
FETCH NEXT FROM detail_cursor INTO #TaskGroupName, #TaskDesc
WHILE ##FETCH_STATUS = 0
BEGIN
INSERT INTO #Checklist (Checklist)
SELECT #TaskDesc
FETCH NEXT FROM detail_cursor INTO #TaskGroupName, #TaskDesc
END
CLOSE detail_cursor
DEALLOCATE detail_cursor
FETCH NEXT FROM header_cursor INTO #HeaderName, #GroupName
END
CLOSE header_cursor;
DEALLOCATE header_cursor
SELECT #Checklist.Checklist, #Checklist.Notes
FROM #Checklist
this can be achieve using PIVOT, Something like this.
IF ( OBJECT_ID('tempdb..#tmpDB') IS NOT NULL )
BEGIN
DROP TABLE #tmpDB
END
SELECT testing ,
production
INTO #tmpDB
FROM (
SELECT
tblDtl.GROUP [group]
, tblDtl.Task [task]
FROM tblHdr
INNER JOIN tblDtl ON tblHdr.CLHId = tblDtl.CLHId
INNER JOIN tblType ON tblHdr.CLHId = tblType.SelectedId
INNER JOIN tblOrder ON tblType.TypeId = tblOrder.Type
ORDER BY tblDtl.CLDDisplayOrder
) P PIVOT ( MAX(task) FOR [group] IN ( testing, production ) ) PVT;
WITH CTEtesting
AS ( SELECT ROW_NUMBER() OVER ( ORDER BY testing ) ctr ,
testing
FROM #tmpDB
WHERE production IS NULL
),
CTEProduction
AS ( SELECT ROW_NUMBER() OVER ( ORDER BY production ) ctr ,
production
FROM #tmpDB
WHERE testing IS NULL
),
CTE
AS ( SELECT testing ,
production
FROM CTEProduction P
FULL JOIN CTEtesting T ON T.ctr = P.ctr
)
SELECT *
FROM CTE
Result:
testing production
-------------------- --------------------
Add object Prompt for input
Report object Show error log
Show error log Show report
Vaidate object Validate input
Validate report Validate object
Vanipulate object NULL
(6 row(s) affected)

Combine results of multiple queries as one result in a SQL Server stored procedure

I need some help with a stored procedure. It contains a loop which runs a Select query. What I get is 3 tables with result if it loops thrice. How can I combine the results as one table?
The procedure is as below:
CREATE PROCEDURE [dbo].[spGetRndQuestions]
#ExamCode Nvarchar(60)
AS
BEGIN
Declare #NosQues Int, #Catgry nvarchar(50)
DECLARE CategCursor CURSOR FOR
(Select Category From tblExamDetail Where ExamCode = #ExamCode)
OPEN CategCursor
FETCH NEXT FROM CategCursor INTO #Catgry
WHILE ##FETCH_STATUS = 0
BEGIN
SET #NosQues = (Select NoOfQues from tblExamDetail Where ExamCode=#ExamCode AND Category=#Catgry)
SELECT TOP(#NosQues) QM.QuestionID, QM.QuestionDesc, QM.QuestionMarks, QM.Answer1, QM.Answer2, QM.Answer3, QM.Answer4 FROM tblQuestionMaster QM
INNER JOIN tblExamMaster EM ON QM.Dept = EM.Dept AND QM.Location = EM.Location AND QM.QuesModule = EM.ExamModule
Where EM.ExamCode=#ExamCode AND QM.Category =#Catgry
Order by NEWID()
/*SELECT TOP (#NosQues) QuestionID,QuestionDesc,Answer1,Answer2,Answer3,Answer4,QuestionMarks from [dbo].[tblQuestionMaster] Where Category=#Catgry AND
Order by NEWID() */
FETCH NEXT FROM CategCursor INTO #Catgry
END
CLOSE CategCursor
DEALLOCATE CategCursor
END
Thanks, your help is truly appreciated.
Create the table variable in start of your SP of appropriate structure of your return table. In each iteration insert selected data to that table. After deallocating cursor select from that table.
CREATE PROCEDURE [dbo].[spGetRndQuestions]
#ExamCode Nvarchar(60) AS
BEGIN
Declare #NosQues Int, #Catgry nvarchar(50)
DECLARE #tbl TABLE(QuestionID int, QuestionDesc ....)
DECLARE CategCursor CURSOR FOR (Select Category From tblExamDetail Where ExamCode=#ExamCode)
OPEN CategCursor
FETCH NEXT FROM CategCursor INTO #Catgry
WHILE ##FETCH_STATUS = 0
BEGIN
SET #NosQues = (Select NoOfQues from tblExamDetail Where ExamCode=#ExamCode AND Category=#Catgry)
INSERT INTO #tbl
SELECT TOP(#NosQues) QM.QuestionID, QM.QuestionDesc, QM.QuestionMarks, QM.Answer1, QM.Answer2, QM.Answer3, QM.Answer4 FROM tblQuestionMaster QM
INNER JOIN tblExamMaster EM ON QM.Dept = EM.Dept AND QM.Location = EM.Location AND QM.QuesModule = EM.ExamModule
Where EM.ExamCode=#ExamCode AND QM.Category =#Catgry
Order by NEWID()
/*SELECT TOP (#NosQues) QuestionID,QuestionDesc,Answer1,Answer2,Answer3,Answer4,QuestionMarks from [dbo].[tblQuestionMaster] Where Category=#Catgry AND
Order by NEWID() */
FETCH NEXT FROM CategCursor INTO #Catgry
END
CLOSE CategCursor
DEALLOCATE CategCursor
SELECT * FROM #tbl
END
Hamlet does answer the question. However, the query you posted could be optimized to eliminate the need for the cursor or table variable. The following code should do that nicely:
CREATE PROCEDURE [dbo].[spGetRndQuestions]
#ExamCode Nvarchar(60)
AS
SELECT
--A.[category],
B.*
FROM tblExamDetail A
CROSS APPLY (
SELECT TOP (A.[NoOfQues])
QM.QuestionID,QM.QuestionDesc,QM.QuestionMarks,
QM.Answer1,QM.Answer2,QM.Answer3,QM.Answer4
FROM tblQuestionMaster QM
INNER JOIN tblExamMaster EM
ON QM.Dept = EM.Dept
AND QM.Location = EM.Location
AND QM.QuesModule = EM.ExamModule
WHERE EM.ExamCode = A.[ExamCode]
AND QM.Category = A.[Category]
ORDER BY NEWID()
) B
WHERE A.[ExamCode] = #ExamCode

insert value from one table to another checking id

I have 2 tables.All the ids are include in table one (Tbl_Distributor). 2nd table have all the names.
I want to add all the names to first table according to id.
My select query as below.
INSERT INTO dbo.Tbl_Distributor(Giv_Name) where dealercode= a.dealercode
SELECT a.dealercode,d.nameinfull
FROM dealerplacement a,dealer d
where a.dealercode= d.dealercode
order by a.dealercode ASC
This returns nameinfull and dealercode. I want to add this nameinfull to Tbl_Distributor .
Please help me to solve this issue.
UPDATE R
SET Giv_Name = D.FirstName
FROM
dbo.Tbl_Distributor R
INNER JOIN dbo.Dealer D
ON R.Dis_ID = D.DealerCode
You cannot use INSERT here. You need to use update. I'd do such a task using cursors.
declare #id int, #name varchar(1000)
DECLARE c CURSOR FOR
SELECT a.dealercode,d.nameinfull
FROM dealerplacement a,dealer d
where a.dealercode= d.dealercode
order by a.dealercode ASC
OPEN c
FETCH NEXT FROM c
INTO #id, #name
WHILE ##FETCH_STATUS = 0
BEGIN
update Tbl_Distributor set Giv_Name = #name where dealercode = #id
FETCH NEXT FROM c
INTO #id, #name
end
CLOSE c;
DEALLOCATE c;
Also, I'd use join in the select statement:
SELECT a.dealercode,d.nameinfull
FROM dealerplacement a inner join dealer d
on a.dealercode= d.dealercode
order by a.dealercode ASC

How to update a column fetched by a cursor in TSQL

Before I go any further: Yes, I know that cursors perform poorly compared with set-based operations. In this particular case I'm running a cursor on a temporary table of 100 or so records, and that temporary table will always be fairly small, so performance is less crucial than flexibility.
My difficulty is that I'm having trouble finding an example of how to update a column fetched by a cursor. Previously when I've used cursors I've retrieved values into variables, then run an update query at each step based upon these values. On this occasion I want to update a field in the temporary table, yet I can't figure out how to do it.
In the example below, I'm trying to update the field CurrentPOs in temporary table #t1, based upon a query that uses #t1.Product_ID to look up the required value. You will see in the code that I have attempted to use the notation curPO.Product_ID to reference this, but it doesn't work. I have also attempted to use an update statement against curPO, also unsuccessfully.
I can make the code work by fetching to variables, but I'd like to know how to update the field directly.
I think I'm probably missing something obvious, but can anyone help?
declare curPO cursor
for select Product_ID, CurrentPOs from #t1
for update of CurrentPOs
open curPO
fetch next from curPO
while ##fetch_status = 0
begin
select OrderQuantity = <calculation>,
ReceiveQuantity = <calculation>
into #POs
from PurchaseOrderLine POL
inner join SupplierAddress SA ON POL.Supplier_ID = SA.Supplier_ID
inner join PurchaseOrderHeader POH ON POH.PurchaseOrder_ID = POL.PurchaseOrder_ID
where Product_ID = curPO.Product_ID
and SA.AddressType = '1801'
update curPO set CurrentPOs = (select sum(OrderQuantity) - sum(ReceiveQuantity) from #POs)
drop table #POs
fetch next from curPO
end
close curPO
deallocate curPO
After doing a bit more googling, I found a partial solution. The update code is as follows:
UPDATE #T1
SET CURRENTPOS = (SELECT SUM(ORDERQUANTITY) - SUM(RECEIVEQUANTITY)
FROM #POS)
WHERE CURRENT OF CURPO
I still had to use FETCH INTO, however, to retrieve #t1.Product_ID and run the query that produces #POs, so I'd still like to know if it's possible to use FETCH on it's own.
Is this what you want?
declare curPO cursor
for select Product_ID, CurrentPOs from #t1
for update of CurrentPOs
open curPO
fetch next from curPO
while ##fetch_status = 0
begin
update curPO set CurrentPOs =
(select sum(<OrderQuantityCalculation>)
from PurchaseOrderLine POL
inner join SupplierAddress SA ON POL.Supplier_ID = SA.Supplier_ID
inner join PurchaseOrderHeader POH ON POH.PurchaseOrder_ID = POL.PurchaseOrder_ID
where Product_ID = curPO.Product_ID
and SA.AddressType = '1801') -
(select sum(<ReceiveQuantityCalculation>)
from PurchaseOrderLine POL
inner join SupplierAddress SA ON POL.Supplier_ID = SA.Supplier_ID
inner join PurchaseOrderHeader POH ON POH.PurchaseOrder_ID = POL.PurchaseOrder_ID
where Product_ID = curPO.Product_ID
and SA.AddressType = '1801')
fetch next from curPO
end
close curPO
deallocate curPO
Maybe you need something like that:
update DataBaseName..TableName
set ColumnName = value
where current of your_cursor_name;
Here's an example to calculate one column based upon values from two others (note, this could be done during the original table select). This example can be copy / pasted into an SSMS query window to be run without the need for any editing.
DECLARE #cust_id INT = 2, #dynamic_val NVARCHAR(40), #val_a INT, #val_b INT
DECLARE #tbl_invoice table(Cust_ID INT, Cust_Fees INT, Cust_Tax INT)
INSERT #tbl_invoice ( Cust_ID, Cust_Fees, Cust_Tax ) SELECT 1, 111, 11
INSERT #tbl_invoice ( Cust_ID, Cust_Fees, Cust_Tax ) SELECT 2, 222, 22
INSERT #tbl_invoice ( Cust_ID, Cust_Fees, Cust_Tax ) SELECT 3, 333, 33
DECLARE #TblCust TABLE
(
Rec_ID INT
, Val_A INT
, Val_B INT
, Dynamic_Val NVARCHAR(40)
, PRIMARY KEY NONCLUSTERED (Rec_ID)
)
INSERT #TblCust(Rec_ID, Val_A, Val_B, Dynamic_Val)
SELECT Rec_ID = Cust_ID, Val_A = Cust_Fees, Val_B = Cust_Tax, NULL
FROM #tbl_invoice
DECLARE cursor_cust CURSOR FOR
SELECT Rec_ID, Val_A, Val_B, Dynamic_Val
FROM #TblCust
WHERE Rec_ID <> #cust_id
FOR UPDATE OF Dynamic_Val;
OPEN cursor_cust;
FETCH NEXT FROM cursor_cust INTO #cust_id, #val_a, #val_b, #dynamic_val;
WHILE ##FETCH_STATUS = 0
BEGIN
UPDATE #TblCust
SET Dynamic_Val = N'#c = "' + LTRIM(STR((#val_a + #val_b), 40)) + N'"'
WHERE CURRENT OF cursor_cust
FETCH NEXT FROM cursor_cust INTO #cust_id, #val_a, #val_b, #dynamic_val;
END
CLOSE cursor_cust
DEALLOCATE cursor_cust
SELECT * FROM #TblCust