SQL Server Forums
Profile | Register | Active Topics | Members | Search | Forum FAQ
 
Register Now and get your question answered!
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 update stored Proc returns null
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

smh
Yak Posting Veteran

USA
82 Posts

Posted - 07/15/2012 :  22:41:28  Show Profile  Reply with Quote
I am updating a table called tblRouteCashSalesHeader by summing values in the related detail table, tblRouteCashSalesDetail.
Routecashsalesheader has a field for bananas total and produce total . The way to determine if the product is a banana type or not (the productId is stored in the detail table) is to check a boolean in the product table: IsBananas. Here is what I have which works fine if there are bananas and non-banana products.

update tblRouteCashSalesHeader
set BananasTotalBoxes = (select sum(boxes) from tblRouteCashSalesDetail where tblRouteCashSalesDetail.RouteCashSalesHeaderID = 2 and
tblRouteCashSalesDetail.ProductID in (select tblproduct.ProductID from tblproduct where isbananas = 1)),

ProduceTotalBoxes = (select sum(boxes) from tblRouteCashSalesDetail where tblRouteCashSalesDetail.RouteCashSalesHeaderID =2 and
tblRouteCashSalesDetail.ProductID in (select tblproduct.ProductID from tblproduct where isbananas = 0))

where tblRouteCashSalesHeader.RouteCashSalesHeaderID = 2

-------------------------------

The problem is that if there are no bananas or if no produce, the select sum(boxes) returns a null value and the procedure crashes. I tried using isnull (see the case statement) but I still get null.

(what I tried)
update tblRouteCashSalesHeader
set ProduceTotalBoxes =
case when (select sum(boxes) from tblRouteCashSalesDetail where tblRouteCashSalesDetail.RouteCashSalesHeaderID = 2 and
tblRouteCashSalesDetail.ProductID in (select tblproduct.ProductID from tblproduct where isbananas = 0)) = null then 0
else
(select sum(boxes) from tblRouteCashSalesDetail where tblRouteCashSalesDetail.RouteCashSalesHeaderID = 2 and
tblRouteCashSalesDetail.ProductID in (select tblproduct.ProductID from tblproduct where isbananas = 0))

end

What can I do?

visakh16
Very Important crosS Applying yaK Herder

India
47099 Posts

Posted - 07/15/2012 :  23:39:45  Show Profile  Reply with Quote

update h 
set h.BananasTotalBoxes = d.BananaTotal,
h.BananasTotalBoxes = d.ProduceTotal 
FROM tblRouteCashSalesHeader h
inner join (
select RouteCashSalesHeaderID ,
sum(case when isbananas = 1 then boxes else 0 end) AS BananaTotal,
sum(case when isbananas = 0 then boxes else 0 end) AS ProduceTotal 
from tblRouteCashSalesDetail 
where tblRouteCashSalesDetail.RouteCashSalesHeaderID = 2 
group by RouteCashSalesHeaderID
)d
On d.RouteCashSalesHeaderID = h.RouteCashSalesHeaderID


------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

smh
Yak Posting Veteran

USA
82 Posts

Posted - 07/16/2012 :  10:45:42  Show Profile  Reply with Quote
Thanks for your help. I see from your answser that I did not make clear the table structures.

tblRouteCashSalesHeader has bananatotalboxes and producetotalboxes.
The tblroutecashsalesdetail has productID and boxes. Each detail record will have a product ID and the number of boxes.

The tblproduct has productID and isbananas, a boolean.

A product is either a banana or not a banana item(a produce item). So all banana items are totaled in the bananaboxtotal and everything not a banana goes into the producetotalboxes of the header table.


so the summing has to reference the product table which is why, I guess, I am having the problems. I could add the field "isbananas" to the detail table and then there would be no problem. Is that the best way to handle this? I know it is the easiest.

so the 3 tables and their fields:

1. Header table
HeaderID
bananatotalboxes
producetotalboxes

2. detail table
DetailID
HeaderID
boxes
productID

3. tblProduct
productID
Isbananas

Edited by - smh on 07/16/2012 10:57:11
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

India
47099 Posts

Posted - 07/16/2012 :  11:31:43  Show Profile  Reply with Quote
its just a matter of additional join


update h 
set h.BananasTotalBoxes = d.BananaTotal,
h.BananasTotalBoxes = d.ProduceTotal 
FROM tblRouteCashSalesHeader h
inner join (
select sd.RouteCashSalesHeaderID ,
sum(case when p.isbananas = 1 then sd.boxes else 0 end) AS BananaTotal,
sum(case when p.isbananas = 0 then sd.boxes else 0 end) AS ProduceTotal 
from tblRouteCashSalesDetail  sd
inner join tblProduct p
ON p.ProductId = sd.ProductId
where sd.RouteCashSalesHeaderID = 2 
group by sd.RouteCashSalesHeaderID
)d
On d.RouteCashSalesHeaderID = h.RouteCashSalesHeaderID


------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

smh
Yak Posting Veteran

USA
82 Posts

Posted - 07/16/2012 :  14:54:18  Show Profile  Reply with Quote
Thank you very much for this solution. It works perfectly. I also needed a sum of the totals for the header field "TotalBoxes" so I added:

update h
set h.BananasTotalBoxes = d.BananaTotal,
h.ProduceTotalBoxes = d.ProduceTotal,
h.TotalBoxes = d.BananaTotal + d.ProduceTotal -- this was added for the total
from ......

This also works. I could not see any other way offhand to get the total of the 2 detail fields. Maybe there is a problem if both are null, but then I presume the totalboxes would be zero.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

India
47099 Posts

Posted - 07/16/2012 :  22:08:16  Show Profile  Reply with Quote

update h 
set h.BananasTotalBoxes = d.BananaTotal,
h.BananasTotalBoxes = d.ProduceTotal,
h.TotalBoxes = d.Total
FROM tblRouteCashSalesHeader h
inner join (
select sd.RouteCashSalesHeaderID ,
sum(case when p.isbananas = 1 then sd.boxes else 0 end) AS BananaTotal,
sum(case when p.isbananas = 0 then sd.boxes else 0 end) AS ProduceTotal ,
sum(sd.boxes) as Total
from tblRouteCashSalesDetail  sd
inner join tblProduct p
ON p.ProductId = sd.ProductId
where sd.RouteCashSalesHeaderID = 2 
group by sd.RouteCashSalesHeaderID
)d
On d.RouteCashSalesHeaderID = h.RouteCashSalesHeaderID


------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

smh
Yak Posting Veteran

USA
82 Posts

Posted - 07/18/2012 :  14:24:21  Show Profile  Reply with Quote
Thank you again. But here is a question. It seems that the 'd' in this query functions a bit like a separate table. Where can I find rules and examples on this technique and when is best to use it. This probably could be done with table varialbes but here it is not needed.

d:
(
select sd.RouteCashSalesHeaderID ,
sum(case when p.isbananas = 1 then sd.boxes else 0 end) AS BananaTotal,
sum(case when p.isbananas = 0 then sd.boxes else 0 end) AS ProduceTotal ,
sum(sd.boxes) as Total
from tblRouteCashSalesDetail sd
inner join tblProduct p
ON p.ProductId = sd.ProductId
where sd.RouteCashSalesHeaderID = 2
group by sd.RouteCashSalesHeaderID
)d


Here is another similar one (also a solution from this site and again, something called MaxTable has been created and is manipulated as a table. I would love to see someone do an article on this or if one has been done on these techniques, to post the reference. Thanks.



WITH MaxTable ( positionID, effectivedate)
AS

( select positionID, max(effectivedate) AS MAXDate
from tblBudgetMaster
WHERE effectivedate <= CONVERT(VARCHAR,@edate,1)
group by positionID
)
insert into tblbudgetmasterselected(BudgetMasterID,positionID,ProjectID, EffectiveDate, FiscalYear,
BudgetedSalaryRate, AnnualSalary, FTE)
(SELECT t.BudgetMasterID, t.positionID, 0, CONVERT(VARCHAR,t.EFFECTIVEDATE,101) AS EFFECTIVEDATE, FiscalYear,
BudgetedSalaryRate, AnnualSalary, FTE
FROM tblBudgetMaster t INNER JOIN MaxTable m ON t.positionID = m.positionID
AND t.effectivedate = m.effectivedate)
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

India
47099 Posts

Posted - 07/18/2012 :  16:41:28  Show Profile  Reply with Quote
former one is called derived table and latter technique common table expressions

see more details here

http://msdn.microsoft.com/en-us/magazine/cc163346.aspx#S1



------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

smh
Yak Posting Veteran

USA
82 Posts

Posted - 07/19/2012 :  11:20:52  Show Profile  Reply with Quote
Thanks. This is very helpful indeed.
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
SQL Server Forums © 2000-2009 SQLTeam Publishing, LLC Go To Top Of Page
This page was generated in 0.11 seconds. Powered By: Snitz Forums 2000