Hi I need help with nested if else statements in MySQL. Please verify if the code below are the same? The C code is what I want to be accomplished in MySQL. I don't have syntax errors. But it seems that I am not getting the right result.
MySQL Stored Proc
IF top10_rank <= 10 AND top100_rank <=10 THEN SET temp_rank = 10;
ELSE SET temp_rank = 100;
END IF;
IF temp_rank = 10 THEN
IF top10_rank_date > top100_rank_date THEN SET rank = top10_rank;
ELSE SET rank = top100_rank;
END IF;
ELSEIF temp_rank = 100 THEN SET rank = top100_rank;
ELSE SET rank = 0;
END IF;
C code
if(top10_rank <= 10 && top100_rank <=10)
{
temp_rank = 10;
}
else
{
temp_rank = 100;
}
if(temp_rank == 10)
{
if(top10_rank_date > top100_rank_date)
{
rank = top10_rank
}
else
{
rank = top100_rank
}
}
else if(temp_rank == 100)
{
rank = top100_rank;
}
else
{
rank = 0;
}
It seems that the pieces are equivalent without regarding such things as size of integer (? may be float) fields and handling of NULL values in SQL.
Code looks not good:
1) This code is unreachable:
else
{
rank = 0;
}
2) It could be shortened - temp_rank could be inlined
3) Probably you need use this function is SELECT, it could be rewritten with CASE operator - to make calls more effective
4) To detect a problem, wrap the C and SQL pieces in functions and specify for which input parameters results are different.
Related
OBJECTIVE
I am looking for a way to update one or both fields using the same CASE statement
UPDATE vendor
SET special_cost =
(
CASE
WHEN
cost > 14
THEN
14
ELSE
SET special_cost = cost, cost = 14
END
)
WHERE upc = '12345678912345'
LOGIC
This is some logic that explains what I want to happen above.
if ($cost > 14) {
$special_cost = 14;
} else {
$special_cost = $cost;
$cost = 14;
}
It does not seem that there is a way to do this with a single CASE statement. Perhaps, this can be done with the mysql IF statement?
You are referring to case expressions not case statements.
You appear to want something like this:
UPDATE vendor
SET special_cost = GREATEST(cost, 14),
cost = 14
WHERE upc = '12345678912345';
I have 3 values saved on Flip-Flops. During a certain state on a FSM I want to detect which is the bigger value and as a result of this, output into a memory a number.
In a side of the top-module file, I'm writing the function like this:
function [1:0] max_val;
input [7:-24] A, B, C;
begin
if (A > B)
begin
if (A > C)
max_val = 2'b01;
else
max_val = 2'b11;
end
else if(B > C)
max_val = 2'b10;
else
max_val = 2'b11;
else
max_val = 2b'00;
end
endfunction
Then during a state of the FSM I do this:
S13:
begin
case (max_val(FF_v1, FF_v2, FF_v3)) /// HERE??
01:
begin
mem_out1 = 1;
end
10:
begin
mem_out2 = 1;
end
11:
begin
mem_out3 = 1;
end
00:
begin
... /// what to do here??
end
endcase
end
I would like to ask if I'm defining and calling the function correctly, when I make use of the function, I understand I must use the same name of the function as "variable" and use it to define a case, right? So how do I define the input of that function, just like I did in "HERE???"
Also, if there are only 3 possible answers, and the one the combinations is unused, what to define in default??
The function declaration is right. Why the input [7:-24] changed it to input [23:0] . Also the if statement nesting was incorrect.
function [1:0] max_val;
input [23:0] A, B, C;
begin
max_val = 0 ;
if (A > B)
begin
if (A > C)
max_val = 2'b01;
else
max_val = 2'b11;
end
else
if(B > C)
max_val = 2'b10;
else
max_val = 2'b11;
end
endfunction
The case statement is fine . Though the values have to be prefixed with 2'b else it will assume the value to be decimal and not match. The case statement need not always have all the options. You can have only 3 or as many as you need . It is better to add a default statement. You can assign the values to x in the default or just print error for simulation purposes.
case ( max_val(a,b,c) )
2'b01 : begin
mem_out_1 = 1;
end
2'b10 : begin
mem_out_2 = 1;
end
2'b11 : begin
mem_out_3 = 1;
end
// no need for 00 case
default : begin
$display(" error val ");
end
endcase
http://www.testbench.in/TB_18_TASK_AND_FUNCTION.html
When I am coding this type of thing I like to "definitively" state what the outputs are going to be for each case, including the default, even if it is an error.
The point being that you could get a compiler that decides to only assign mem_out1 when you hit the 2'b01 state and leaves it set forever because nothing ever sets it back to zero. Not sure if that was the point of the design or if it might be undesired behavior.
case ( max_val(a,b,c) )
2'b01 : begin
{mem_out_3,mem_out_2,mem_out_1} = 3'b001;
end
2'b10 : begin
{mem_out_3,mem_out_2,mem_out_1} = 3'b010;
end
2'b11 : begin
{mem_out_3,mem_out_2,mem_out_1} = 3'b100;
end
// no need for 00 case
default : begin
// {mem_out_3,mem_out_2,mem_out_1} = 3'b000; // Uncomment if you need to control the output in the event of an error
$display(" error val ");
end
endcase
I think this a pretty classical setting: Suppose I have a table tab1, with columns c1, c2. Then I want to select c1, c2 as variable of a function fun(a,b) in another select:
SELECT fun(#a,#b) as r FROM (SELECT #a:=c1, #b:=c2 FROM tab1) AS tab ORDER BY r LIMIT 10;
The fun is pre-defined in PHP:
function fun($d, $t){
$timenow = time();
$perd = 45000;
$di = (int)$d;
$tf = (float)$t;
if ($di === 0)
{
return 0;
}else{
return (Log($di)/Log(10)+($timenow-$tf)/$perd);
}
}
The problem is that the variable is not updated at all. I build a test environment in http://sqlfiddle.com/#!9/9ffd6, the fun(#a,#b) is replaced by #a for simplicity.
UPDATE
It seems that my original question canot properly describe my problem. And I updated it, thanks to #wajeeh, the solution could be:
translate my php function into MYSQL form (it is a litter hard for me)
Use php function, but return the mysql results as array. (In that case I need to write the odering function by hand! and then (maybe) need another SELECT of MYSQL?)
You can call the function directly like this:
Select func(c1, c2) as r From tab1;
SQLFiddle
public function func($param1, $param2) {
// your code
}
$query = "Select c1, c2 From tab";
$stmt = $link->prepare($query);
if ($stmt->execute()) {
while ($row = $stmt->fetch(PDO::FETCH_NAMED)) {
func($row["c1"], $row["c2"]);
}
}
I'm not sure what the PHP function does or how it works so this may not be a perfect translation to a MySQL function but hopefully you can use it as a starting point.
DELIMITER //
CREATE FUNCTION FUN(d INT, t FLOAT)
RETURNS FLOAT DETERMINISTIC NO SQL
BEGIN
IF d = 0 THEN
RETURN 0;
ELSE
RETURN LOG(d)/LOG(10)+(UNIX_TIMESTAMP()-t)/45000;
END IF;
END//
DELIMITER ;
So you can do that:
Select IF(c1 = 0, 0, LOG(c1)/LOG(10)+(UNIX_TIMESTAMP()-c2)/45000) as r From tab1
SQLFiddle
Thanks to #Matt
I made a Stored Procedure.
When i tested it with workbench call, it worked well. but if i called that
inside webservice call, i got an 1217 result. (defined in procedure)
myTable is made with 3 column (user_no, index, count)
and this procedure is for subtracting multiple row's count.
DECLARE _affected_count INT DEFAULT 0;
IF ( o_ouput1 < i_input1 ) THEN
SET o_result = 1211;
LEAVE proc_body;
ELSEIF ( i_input1 > 0 ) THEN
SET _affected_count = _affected_count + 1;
END IF;
IF ( o_ouput2 < i_input2 ) THEN
SET o_result = 1212;
LEAVE proc_body;
ELSEIF ( i_input2 > 0 ) THEN
SET _affected_count = _affected_count + 1;
END IF;
// Same for input3~input6
UPDATE myTable
SET count = CASE WHEN index = 1 AND i_input1 > 0 AND count >= i_input1 THEN count - i_input1
WHEN index = 2 AND i_input2 > 0 AND count >= i_input2 THEN count - i_input2
WHEN index = 3 AND i_input3 > 0 AND count >= i_input3 THEN count - i_input3
WHEN index = 4 AND i_input4 > 0 AND count >= i_input4 THEN count - i_input4
WHEN index = 5 AND i_input5 > 0 AND count >= i_input5 THEN count - i_input5
WHEN index = 6 AND i_input6 > 0 AND count >= i_input6 THEN count - i_input6
ELSE count END
WHERE user_no = i_user_no AND index IN ( 1, 2, 3, 4, 5, 6 );
IF ( ROW_COUNT() <> _affected_count ) THEN
SET o_result = 1217;
LEAVE proc_body;
END IF;
The Problem is.. If i call this procedure in workbench, it works well.
I can't understand why it's different when i called it with workbench and webmethod.
Is there anybody who can explain this?
I Found An Answer
Use Affected Rows Option in on with Workbench, but not with webservice default.
http://dev.mysql.com/doc/refman/5.5/en//information-functions.html#function_row-count
I know languages like PHP has switch case control structure that supports multiple validations in a single case statement like,
Switch $x {
case 1,2,3:
$a = 0;
break;
case 5,6:
$a = 1;
break;
}
Similarly can this be done in MYSQL? I tried below, which really didn't work though :(
CASE vc_shape
WHEN ('02' OR '51') THEN SET dc_square_1 = dc_square_1 + dc_row_total;
WHEN ('06' OR '30' OR 83) THEN SET dc_square_2 = dc_square_2 + dc_row_total;
.....
.....
ELSE
BEGIN
END;
END CASE;
Any ideas how can I achieve this?
Use the other format for CASE statements:
CASE
WHEN vc_shape IN ('02', '51') THEN SET dc_square_1 = dc_square_1 + dc_row_total;
WHEN vc_shape IN ('06', '30', '83') THEN SET dc_square_2 = dc_square_2 + dc_row_total;
.....
.....
ELSE
BEGIN
END;
END CASE;