Duplicate Entry Mysql Primary - mysql

Got some error within this code,
have tried to debug but couldn't find the answer.
Does anyone can correct me please?
BEGIN
DECLARE FINALID VARCHAR(8);
DECLARE MAXIDCOMPANY VARCHAR(8);
SELECT MAX(SUBSTRING(company.idCompany,3,8))+1 INTO MAXIDCOMPANY
FROM company
WHERE SUBSTRING(company.idCompany,1,2) = SUBSTRING(nmCompany,1,2);
IF MAXIDCOMPANY > 0 AND MAXIDCOMPANY < 10 THEN
SET FINALID = CONCAT(SUBSTRING(nmCompany,1,2),'00', CONVERT(MAXIDCOMPANY USING latin1));
ELSEIF MAXIDCOMPANY > 9 AND MAXIDCOMPANY < 100 THEN
SET FINALID = CONCAT(SUBSTRING(nmCompany,1,2),'0', CONVERT(MAXIDCOMPANY USING latin1));
ELSEIF MAXIDCOMPANY > 99 THEN
SET FINALID = CONCAT(SUBSTRING(nmCompany,1,2), CONVERT(MAXIDCOMPANY USING latin1));
END IF;
IF MAXIDCOMPANY IS NULL THEN
SET FINALID = CONCAT(SUBSTRING(nmCompany,1,2),'001');
END IF;
INSERT INTO company
(company.idCompany, company.nmCompany, company.country, company.address, company.region, company.joinDate, company.quota, company.createdUser, company.createdDate, company.updatedUser, company.updatedDate)
VALUES
(FINALID, nmCompany, country, address, region, joinDate, quota, createdUser, NOW(), updatedUser, updatedDate);
END
That's the code, the program stuck to counter after next to 1000.
EXAMPLE :
When I add the data for example IN1000 as the idCompany, it always stucks on that number, but when I query the maximum data it shows IN999 only, why not the IN1000
Huge thanks

Because the function max combine with SUB-STRING will return the maximum value within variable character, and the solution for this is substitute it with count function and the logic count will return the maximum value.
SELECT COUNT(company.idCompany) + 1 INTO MAXIDCOMPANY from company where SUBSTRING(company.idCompany,1,2) = SUBSTRING(company.idCompany,1,2);
based on my business proses, thank you all for the answer..

Related

Add 2 SUM CASE statements as a column update in MySQL

I think I have this almost figured out but after 50+ Google searches, I ask this: How can I add a column to a db that is essentially a sumif function? I've seen many related questions as simple Select statements for just looking at the table in a mini table but I was hoping to actually add a column that would show these totals. I'm taking this and then pulling the data into R for further analysis.
In Excel it works like so with [ ] denoting columns of a table. It is split into 2 areas via the Serial #. The first 6 digits of the serial indicate the "parent" and the later half indicate the "child". One parent can have multiple children, as seen with BSA101 below. What I'm trying to do is sum all the costs that went into making the child (parent + child costs). So the total parent costs, get allocated to both children below.
"Packing" is the last step so this is where I'd want the totals to end up so there are no duplicates.
Example
=IF(LEN([serial])>6,IF([process]="Packing",SUMIF([serial],[#serial],[process_cost])+SUMIF([serial],LEFT([#serial],6),[process_cost]),""),"")
serial process process_cost total_child_cost
BSA101A33 Packing 10 160
BSA101A34 Packing 10 195
BSA101 Cast 50 ""
BSA101 Mold 30 ""
BSA101 Mold 30 ""
BSA101A33 Finish 15 ""
BSA101A34 Finish 25 ""
BSA101A33 Polish 25 ""
BSA101A34 Polish 50 ""
^desired table result above
MySQL attempt:This post helped me Adding Case Statements
SQL Fiddle: http://sqlfiddle.com/#!9/b0e58
Here I've added a column in data called total_cost. Right now I'm getting an "Invalid use of group function" error which after researching, talks about a HAVING clause but not sure where to place it.
UPDATE data
SET total__child_cost =
(CASE WHEN length(serial) > 6
AND process = 'Packing'
THEN
IF(serial = serial, sum(process_cost),0) END)
+
(CASE WHEN left(serial,6) = serial
THEN sum(process_cost)
END)
This ended up being the solution.
DELIMITER //
CREATE FUNCTION `getParent1`(inSerialn Varchar(20)) RETURNS int(11)
BEGIN
Declare parent varchar(20);
Declare result int;
set parent = left(inSerialn, 6);
set result = (Select sum(process_cost) From mfng.data where serialn = parent);
return result;
END //
DELIMITER //
CREATE FUNCTION `getChild1`(inSerialn Varchar(20)) RETURNS int(11)
BEGIN
Declare result int;
set result = (Select sum(process_cost) FROM mfng.data where serialn = inSerialn);
return result;
END//
UPDATE mfng.data set total_child_cost =
(case when length(serialn) > 6 AND pdn_process = 'Packing'
THEN
getChild1(serialn) + getParent1(serialn)
ELSE
0 END);
//

MySQL user-defined function returns incorrect value when used in a SELECT statement

I met a problem when calling a user-defined function in MySQL. The computation is very simple but can't grasp where it went wrong and why it went wrong. Here's the thing.
So I created this function:
DELIMITER //
CREATE FUNCTION fn_computeLoanAmortization (_empId INT, _typeId INT)
RETURNS DECIMAL(17, 2)
BEGIN
SET #loanDeduction = 0.00;
SELECT TotalAmount, PeriodicDeduction, TotalInstallments, DeductionFlag
INTO #totalAmount, #periodicDeduction, #totalInstallments, #deductionFlag
FROM loans_table
WHERE TypeId = _typeId AND EmpId = _empId;
IF (#deductionFlag = 1) THEN
SET #remaining = #totalAmount - #totalInstallments;
IF(#remaining < #periodicDeduction) THEN
SET #loanDeduction = #remaining;
ELSE
SET #loanDeduction = #periodicDeduction;
END IF;
END IF;
RETURN #loanDeduction;
END;//
DELIMITER ;
If I call it like this, it works fine:
SELECT fn_computeLoanAmortization(3, 4)
But if I call it inside a SELECT statement, the result becomes erroneous:
SELECT Id, fn_computeLoanAmortization(Id, 4) AS Amort FROM emp_table
There's only one entry in the loans_table and the above statement should only result with one row having value in the Amort column but there are lots of random rows with the same Amort value as the one with the matching entry, which should not be the case.
Have anyone met this kind of weird dilemma? Or I might have done something wrong from my end. Kindly enlighten me.
Thank you very much.
EDIT:
By erroneous, I meant it like this:
loans_table has one record
EmpId = 1
TypeId = 2
PeriodicDeduction = 100
TotalAmount = 1000
TotalInstallments = 200
DeductionFlag = 1
emp_table has several rows
EmpId = 1
Name = Paolo
EmpId = 2
Name = Nikko
...
EmpId = 5
Name = Ariel
when I query the following statements, I get the correct value:
SELECT fn_computeLoanAmortization(1, 2)
SELECT Id, fn_computeLoanAmortization(Id, 2) AS Amort FROM emp_table WHERE EmpId = 1
But when I query this statement, I get incorrect values:
SELECT Id, fn_computeLoanAmortization(Id, 2) AS Amort FROM emp_table
Resultset would be:
EmpId | Amort
--------------------
1 | 100
2 | 100 (this should be 0, but the query returns 100)
3 | 100 (same error here)
...
5 | 100 (same error here up to the last record)
Inside your function, the variables you use to retrieve the values from the loans_table table are not local variables local to the function but session variables. When the select inside the function does not find any row, those variables still have the same values as from the previous execution of the function.
Use real local variables instead. In order to do that, use the variables names without # as a prefix and declare the variables at the beginning of the function. See this answer for more details.
I suspect the problem is that the variables in the INTO are not re-set when there is no matching row.
Just set them before the INTO:
BEGIN
SET #loanDeduction = 0.00;
SET #totalAmount = 0;
SET #periodicDeduction = 0;
SET #totalInstallments = 0;
SET #deductionFlag = 0;
SELECT TotalAmount, PeriodicDeduction, TotalInstallments, DeductionFlag
. . .
You might just want to set them to NULL.
Or, switch your logic to use local variables:
SET v_loanDeduction = 0.00;
SET v_totalAmount = 0;
SET v_periodicDeduction = 0;
SET v_totalInstallments = 0;
SET v_deductionFlag = 0;
And so on.

Calling stored procedure in MySQL takes forever to execute

I have a stored procedure which I'm trying to call, and it takes forever to execute. I have no idea what's wrong. A similar stored procedure in another database executes perfectly. I'm not well-versed with MySQL Workbench, so I don't know if the database settings are different or something.
Following is my stored procedure:
CREATE
DEFINER = `admin`#`%`
PROCEDURE `calculate_daily_coil_moved_by_crane_data`()
BEGIN
set #curr_date = curdate();
set #pre_date = date_add(curdate(), interval -1 day);
set #a_shift_start_ts = concat(#pre_date, ' 06:00:00');
set #a_shift_end_ts = concat(#pre_date, ' 13:59:59');
set #b_shift_start_ts = concat(#pre_date, ' 14:00:00');
set #b_shift_end_ts = concat(#pre_date, ' 21:59:59');
set #c_shift_start_ts = concat(#pre_date, ' 22:00:00');
set #c_shift_end_ts = concat(#curr_date, ' 05:59:59');
SELECT #curr_date,
#pre_date,
#a_shift_start_ts,
#a_shift_end_ts,
#b_shift_start_ts,
#b_shift_end_ts,
#c_shift_start_ts,
#c_shift_end_ts;
#SET DATA
insert into daily_coil_move_by_crane_data_for_report (crane_id, crane_name, date, a_shift, b_shift, c_shift)
select cr.id, cr.name, #pre_date, 0, 0, 0
from yms_phase3.crane cr
where active = 1
order by cr.name;
#----------------------------------------------------------------------------------------------------
#--> COILS MOVED BY CRANE A Shift <--
#----------------------------------------------------------------------------------------------------
SET #shift = 'A';
#FETCH ROW DATA
update daily_coil_move_by_crane_data_for_report
set a_shift = ifnull((select COUNT(*)
FROM yms_phase3.workorder_history in_data
where in_data.crane_id = daily_coil_move_by_crane_data_for_report.crane_id
and current_execution_status IN (6 , 7)
and in_data.pick_ts between #a_shift_start_ts and #a_shift_end_ts
group by in_data.crane_name), 0)
where (a_shift is null or a_shift = 0);
#----------------------------------------------------------------------------------------------------
#--> COILS MOVED BY CRANE B Shift <--
#----------------------------------------------------------------------------------------------------
SET #shift = 'B';
#FETCH ROW DATA
update daily_coil_move_by_crane_data_for_report
set b_shift = ifnull((select COUNT(*)
FROM yms_phase3.workorder_history in_data
where in_data.crane_id = daily_coil_move_by_crane_data_for_report.crane_id
and current_execution_status IN (6 , 7)
and in_data.pick_ts between #b_shift_start_ts and #b_shift_end_ts
group by in_data.crane_name), 0)
where (b_shift is null or b_shift = 0);
#----------------------------------------------------------------------------------------------------
#--> COILS MOVED BY CRANE C Shift <--
#----------------------------------------------------------------------------------------------------
SET #shift = 'C';
#FETCH ROW DATA
update daily_coil_move_by_crane_data_for_report
set c_shift = ifnull((select COUNT(*)
FROM yms_phase3.workorder_history in_data
where in_data.crane_id = daily_coil_move_by_crane_data_for_report.crane_id
and current_execution_status IN (6 , 7)
and in_data.pick_ts between #c_shift_start_ts and #c_shift_end_ts
group by in_data.crane_name), 0)
where (c_shift is null or c_shift = 0);
#----------------------------------------------------------------------------------------------------
#INSERT ALL CRANE ENTRY
insert into daily_coil_move_by_crane_data_for_report (crane_id, crane_name, date, a_shift, b_shift, c_shift)
select -1, 'ALL', #pre_date, SUM(a_shift), sum(b_shift), sum(c_shift)
from daily_coil_move_by_crane_data_for_report
where date = #pre_date
group by date;
#UPDATE TOTAL
update daily_coil_move_by_crane_data_for_report
set total_coils_moved = (a_shift + b_shift + c_shift)
where date = #pre_date;
END
Also tried to execute the query from Java using the following:
jdbcTemplate.execute("CALL calculate_daily_coil_moved_by_crane_data;");
But it gives me the following Exception:
java.sql.SQLException: Lock wait timeout exceeded
Any workaround I can do to solve this?
Please try and edit the configuration file, also search for the same here on stack. There are certain possibilities while checking this out,
Check and edit the config file on Hard drive for MySQL increase the cache capacity and default values as the default values are in KB's the memory allocated is very less and to execute such a big procedure it should at least be some MB.
Increase the connection String timeout, that is by setting up right time in seconds. by default it is 60 seconds, which is very less for executing such a procedure, I think in c# at least we set it to '0' seconds which means that it shall not get timed-out till the query is executed.
If Any left Joins/ inner query please try and check whether the same output is produced in inner joins ? as inner joins are faster than left or right joins.
Add Indexes, have foreign key references properly mapped for faster execution of query.
Hope it works.

How to Auto Increment ID Numbers with Letters and Numbers

How to Auto Increment ID Numbers with Letters and Numbers, example "KP-0001" it will increment to "KP-0002"
Thank you!
here is a useful article
auto increment with a string of numbers and letters
But basically I encourage you to create your own algorithm on this. You can add that algorithm in BEFORE INSERT trigger. Or you can do that on the front-end.
Example of pseudocode for the algorthm
get the lastID [KP-0001]
remove some characters and put it in a variable [KP-]
convert the remaining into number since it's a string [0001]
increment by 1 [1 + 1 = 2]
convert it back to string and pad zero on the right [0002]
concatenate the variable and the newly incremented number [KP-0002]
save it.
I tried to do that in many ways but was unable to reach the solution... I also used triggers but that too didn't help me...
But I found a quick solution for that...
For example you want your employee to have employee codes 'emp101', 'emp102',...etc.
that too with an auto increment...
First of all create a table with three fields the first field containing the letters you want to have at the beginning i.e."emp", the second field containing the auto increasing numbers i.e 101,102,..etc., the third field containing both i.e 'emp101', 'emp102',...etc.
CREATE TABLE employee
(
empstr varchar( 5 ) default 'emp',
empno int( 5 ) AUTO_INCREMENT PRIMARY KEY ,
empcode varchar( 10 )
);
now providing an auto_increment value to empno.
ALTER TABLE employee AUTO_INCREMENT=101;
now coming to the topic... each time you insert values you have to concatenate the first two fields to get the values for the third field
INSERT INTO employee( empcode )
VALUES ('xyz');
UPDATE employee SET empcode = concat( empstr, empno ) ;
You can't auto increment varchar data type. Other way of doing this is to bifurcate varchar column into two different columns one will have integer part and other will have alphabet like in your case KP- once you auto increment all integer rows just concatenate these two columns
CREATE TABLE Customer (
CUSId INT NOT NULL IDENTITY(1, 1) PRIMARY KEY
,CUSKey AS 'Cus' + RIGHT('000' + CONVERT(VARCHAR(5), CUSId), 6) PERSISTED
,CusName VARCHAR(50)
,mobileno INT
,Gender VARCHAR(10)
)
Auto-increment is an integer, so adding text will not be possible.
Check out this question for other references.
Make a procedure, in my case MySQL.
CREATE PROCEDURE MOSTRAR_CODIGO_CLASE_PRODUCTO()
BEGIN
declare max varchar(10);
declare num int;
declare CCodigo varchar(10);
set max = (select MAX(Codigo_CP) from CLASE_PRODUCTO);
set num = (SELECT LTRIM(RIGHT(max,4)));
if num>=1 and num <=8 then
set num = num + 1;
set CCodigo = (select concat('CP000' , CAST(num as CHAR)));
elseif num>=9 and num <=98 then
set num = num + 1;
set CCodigo = (select concat('CP00' , CAST(num as CHAR)));
elseif num>=99 and num <=998 then
set num = num + 1;
set CCodigo = (select concat('CP0' , CAST(num as CHAR)));
elseif num>=999 and num <=9998 then
set num = num + 1;
set CCodigo = (select concat('CP' , CAST(num as CHAR)));
else
set CCodigo=(select 'CP0001');
end if;
SELECT MAX(CCodigo) AS Codigo_CP FROM CLASE_PRODUCTO;
END $
Java Class
public static boolean insertarClaseProducto(ClaseP cp){
boolean resp = false;
Connection cn;
Connection con = new Connection();
cn = con.connect();
try{
CallableStatement cs = cn.prepareCall("CALL REGISTRAR_CLASE_PRODUCTO (?)");
cs.setString(1, cp.getNombreCP());
int i = cs.executeUpdate();
if(i==1)
resp = true;
else
resp = false;
}catch(Exception e){System.out.println(e);}
return resp;
}
returns:
Codigo_MP Nombre_MP Estado_MP
MP0001 LG HAB
MP0002 GENIUS HAB
MP0003 MICRONICS HAB
MP0004 SONY HAB
MP0005 PANASONIC HAB

Need to use a nested cursor and getting "invalid object name"

First, let me state right off that I'm well aware that cursors are generally evil and shouldn't be used - I'm all about using sets, but just couldn't come up with a set-based solution to this particular problem. If you tell me to go do some set-based operations, well, I'm all for it, if you can tell me how you'd code this particular problem.
Basically, I've got a number of stock items for which I need to make purchases. I want to make purchases based upon the cheapest available price, where I know the suppliers' prices and their stock levels. There's also a pack-size issue in here, wherein I want to buy by pack-size if possible.
I've already pulled a list of the things I need to purchase into #needorders, and suppliers' stock levels and prices into #orderedprices. Below I'm iterating through cursor CUR_NEEDED and creating a secondary cursor CUR_AVAILABLE:
DECLARE CUR_NEEDED CURSOR LOCAL SCROLL_LOCKS
FOR
SELECT GoodID
, ConditionID
, QuantityToShip
, OrderStatusID
, RetailerID
, PackSize
FROM #needorders
ORDER BY GoodID
, ConditionID
, PurchaseDate DESC
FOR UPDATE
OPEN CUR_NEEDED
FETCH NEXT FROM CUR_NEEDED INTO #GoodID, #ConditionID, #QuantityToShip, #OrderStatusID, #RetailerID, #PackSize
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE CUR_AVAILABLE CURSOR LOCAL SCROLL_LOCKS
FOR
SELECT SupplierStocklistItemID
, SupplierID
, StockLevel
, SupplierCurrencyID
, CostPrice
FROM #orderedprices
WHERE #orderedprices.GoodID = #GoodID
AND #orderedprices.ConditionID = #ConditionID
AND #orderedprices.StockLevel > 0
ORDER BY #orderedprices.PriceRank
FOR UPDATE
OPEN CUR_AVAILABLE
FETCH NEXT FROM CUR_AVAILABLE INTO #SupplierStocklistItemID, #SupplierID, #StockLevel, #SupplierCurrencyID, #CostPrice
WHILE ##FETCH_STATUS = 0
BEGIN
/*
Buy as many #PackSize as we need to cover how many we require, unless the supplier
only has a certain number, in which case buy that number.
E.g., need 14, pack size 5, 2 suppliers
Supplier A has 11
Supplier B has 40
Buy 9 from Supplier A, with our remaining need being 3.
Buy 5 from supplier B, with our remaining need being -2
*/
--feed rows into #supplierpurchasesbase while #StockLevel > 0
--Figure out how many we need to buy, based upon PackSize
IF #QuantityToShip % #PackSize > 0
BEGIN
SET #Buy = #QuantityToShip - #QuantityToShip % #PackSize + #PackSize
END
ELSE
BEGIN
SET #Buy = #QuantityToShip
END
IF #StockLevel < #Buy
BEGIN
--PRINT 'Supplier only has ' + CAST(#StockLevel AS VARCHAR) + ' for us to buy.'
SET #Buy = #StockLevel
END
INSERT INTO #supplierpurchasesbase (
GoodID
, ConditionID
, SupplierStocklistItemID
, Quantity
, SupplierID
, SupplierCurrencyID
, CostPrice
, RetailerID )
SELECT #GoodID
, #ConditionID
, #SupplierStocklistItemID
, #Buy
, #SupplierID
, #SupplierCurrencyID
, #CostPrice
, #RetailerID
--update #QuantityToShip & the row in CUR_AVAILABLE
IF #StockLevel <= #Buy
BEGIN
UPDATE CUR_AVAILABLE
SET StockLevel = #StockLevel - #Buy
WHERE CURRENT OF CUR_AVAILABLE
SET #QuantityToShip = 0
END
ELSE
BEGIN
UPDATE CUR_AVAILABLE
SET StockLevel = 0
WHERE CURRENT OF CUR_AVAILABLE
SET #QuantityToShip = #QuantityToShip - #Buy
END
--update the stocklevel so we don't see the thing again if we've used it up.
IF #QuantityToShip = 0 --Don't need any more
BEGIN
UPDATE CUR_NEEDED
SET OrderStatusID = #StatusPendingPO
WHERE CURRENT OF CUR_NEEDED
BREAK
END
ELSE --Need more, move next, if we can
FETCH NEXT FROM CUR_AVAILABLE INTO #SupplierStocklistItemID, #SupplierID, #StockLevel, #SupplierCurrencyID, #CostPrice
END
CLOSE CUR_AVAILABLE
DEALLOCATE CUR_AVAILABLE
FETCH NEXT FROM CUR_NEEDED INTO #GoodID, #ConditionID, #QuantityToShip, #OrderStatusID, #RetailerID, #PackSize
END
CLOSE CUR_NEEDED
DEALLOCATE CUR_NEEDED
The problem I'm running into is that I get I'm getting the error
Invalid object name 'CUR_AVAILABLE'.
when I'm attempting to update CURRENT OF CUR_AVAILABLE.
I've tried defining the CUR_AVAILABLE cursor as #CUR_AVAILABLE but get a different error. I've tried defining the CUR_AVAILABLE cursor outside of the WHILE loop of CUR_NEEDED, I've tried not closing / deallocating the cursor, etc. None of this seems to work.
Any ideas where I'm going wrong, here (other than not using sets, unless you've got a set-based solution)?
The following query uses a recursive CTE and, therefore, can't be considered a truly set-based solution. Nevertheless, I would still expect it to perform better than your two cursors (or to be worth trying, at the very least):
WITH buys (
GoodID,
ConditionID,
SupplierStocklistItemID,
Quantity,
SupplierID,
SupplierCurrencyID,
CostPrice,
RetailerID,
PriceRank,
RemainingNeed,
PackSize
)
AS (
SELECT
GoodID,
ConditionID,
SupplierStocklistItemID = 0,
Quantity = 0,
SupplierID = 0,
SupplierCurrencyID = 0,
CostPrice = CAST(0.00 AS decimal(10,2)),
RetailerID,
PriceRank = 0,
RemainingNeed = QuantityToShip,
PackSize
FROM #needorders
UNION ALL
SELECT
p.GoodID,
p.ConditionID,
p.SupplierStockListItemID,
Quantity = y.CurrentBuy,
p.SupplierID,
p.SupplierCurrencyID,
p.CostPrice,
b.RetailerID,
p.PriceRank,
RemainingNeed = b.RemainingNeed - y.CurrentBuy,
b.PackSize
FROM #orderedprices p
INNER JOIN buys b ON p.GoodID = b.GoodID
AND p.ConditionID = b.ConditionID
AND p.PriceRank = b.PriceRank + 1
CROSS APPLY (
SELECT RemainingNeedAdjusted =
(b.RemainingNeed + b.PackSize - 1) / b.PackSize * b.PackSize
) x
CROSS APPLY (
SELECT CurrentBuy = CASE
WHEN x.RemainingNeedAdjusted > p.StockLevel
THEN p.StockLevel
ELSE x.RemainingNeedAdjusted
END
) y
WHERE p.StockLevel > 0
AND b.RemainingNeed > 0
)
SELECT
GoodID,
ConditionID,
SupplierStocklistItemID,
Quantity,
SupplierID,
SupplierCurrencyID,
CostPrice,
RetailerID
FROM buys
WHERE PriceRank > 0
ORDER BY
GoodID,
ConditionID,
PriceRank
Basically, the CTE forms the rows almost identical to those your query is inserting into #supplierpurchasesbase, except it additionally features auxiliary columns serving as kind of internal variables. (They are not pulled by the final SELECT, though.)
The anchor part forms a set of 0-quantity records based on the #needordered table, together with the initial values for the auxiliary columns. The recursive part contains all the logic: calculates the quantity to buy, updates the "remaining need" quantity for the next iteration, checks whether the next iteration is needed.
Certain assumptions have been made, and I hope you'll be able find your way around them if they do not match your real situation. For instance, quantities, pack sizes are assumed to be integer, and part of the logic relies on that, because it uses integral division. It is also assumed that PriceRank is a sequence of integers starting from 1, unique per (GoodID, ConditionID).
This script, as well as a minimal test setup, can be found, tested, modified, and tested on SQL Fiddle.
The problem was twofold: The update syntax should not be:
UPDATE CUR_AVAILABLE
SET StockLevel = #StockLevel - #Buy
WHERE CURRENT OF CUR_AVAILABLE
Rather, the syntax should be:
UPDATE #orderedprices
SET StockLevel = #StockLevel - #Buy
WHERE CURRENT OF CUR_AVAILABLE
Also, in order to be updatable, the temp table needed to have a primary key:
ALTER TABLE #orderedprices ADD CONSTRAINT PRIMARY KEY CLUSTERED (RowCtr)
Lesson learned, I guess, but it certainly took me a fair bit of grief to find the solution!