IFNULL is not working - mysql

Hi I am working with mysqli to replace a default value on the table if the data from the database is NULL. I already tried it on PHPmyAdmin and it's working but not on my code :(
Here's my SELECT query:
$query="SELECT pro_id, pro_name, unit_name, cat_name, IFNULL(quantity,'empty') AS quantity FROM products, unit, categories WHERE products.unit=unit.unit_id AND products.pro_cat=categories.cat_id";

If, as one of your comments seems to indicate, the error you're getting is:
Incorrect parameter count in the call to native function 'ISNULL'
then it's a simple typo. ISNULL is not the same as IFNULL.
The former returns a truth value if its one argument is null.
The latter returns the second argument if the first is null, otherwise it returns the first argument.
You can see this if you put the following code into SqlFiddle:
-- DDL
create table xyzzy (plugh int);
insert into xyzzy (plugh) values (null);
insert into xyzzy (plugh) values (42);
select plugh, isnull(plugh) from xyzzy;
select plugh, ifnull(plugh,-1) from xyzzy;
select plugh, isnull(plugh,-1) from xyzzy;
The output is as expected for the first two select statements while the third generates the error you describe:
plugh isnull(plugh)
------ -------------
(null) 1
42 0
plugh ifnull(plugh,-1)
------ ----------------
(null) -1
42 42
Incorrect parameter count in the call to native function 'isnull'

Related

Scalar function in mysql returns inconsistent values. Depending on where is being called

I create a scalar function that calculates that multiplies the value of two columns and store that the result in a variable. That variable is returned. My objective is to use my function inside an insert statement in order to pupulate a field with the return value.
My problem is that when I call my function like so select calculate_price(4,5) I obtain the desired result. However, when I call the function inside the insert statement I get an unexpected result.
My code looks like so:
CREATE DEFINER=`root`#`localhost` FUNCTION `calculate_price`(idcart int, idProduct int) RETURNS int
DETERMINISTIC
BEGIN
select price*quantity into #price
from product inner join test_product_quantity_cart
on product.id_product=test_product_quantity_cart.id_product
where id_cart=idcart and test_product_quantity_cart.id_product=idProduct;
RETURN #price;
END
a row in my table test_product_quantity_cart looks like this:
id_cart=4
quantity=5
id_product=2
price_product= -- expected 20
the related row in my table product looks like so:
id_product=2
price=4
if I call my function this way select calculate_price(4,2), I get 20. Which makes sense because the price of product with id 2 is 4. The quantity is 5, so 4*5=20.
However, when I use the function inside a insert statement in order to create a new row like so:
insert into test_product_quantity_cart(id_cart,quantity,id_product,price_product )
values (4,5,2, calculate_price(4,2))
I get 45.
I would like to know what I am doing wrong that causes this inconsistente behavor.
Thank you for your help.
When you are doing the insert the db has not yet been written to when the function is invoked AND the function may find a preexisting row in test_product_quantity_cart so using the fiddle provided by akina and changing the first insert to 4/10/2 the second insert calculates a price of 40. Also the first insert does not acquire a price.
In my view a trigger would be more appropriate anyway.

How to catch empty input value within MySQL statement?

In MySQL I need to find multiple IDs within a table, but in some cases the search ID is missing. There is no way around this and I can not put this into programming application logic as it is a grafana dashboard filter. In case no filter it will provide no value at all for the variable.
Minimal example:
SELECT *
FROM tbl
where
-- try to catch empty value
case
when "$filter_ids" then
id in ($filer_ids)
-- id in ('1','2')
-- find_in_set(id, 1,2)
end
AND other_id = 4
-- Possible values for $filter_ids:
-- ''
-- '1'
-- '1','18'
-- Alternativ cases, also possible:
-- empty for no value
-- 1
-- 1,18
I tried both, find_in_set and IN. But both result in an MySQL error in case there is no value (no filter set).
How could I catch this in MySQL?
You can add an empty string to IN or FIND_IN_SET, if you have no ids. that would nozt produce an error
CREATE tABLE TEST(id int)
SELECT * FROM TEST WHERE id in ("") OR FIND_IN_SET(id,'')
| id |
| -: |
db<>fiddle here

get 0 when emptyornull values else max(id) when column datatype is numeric in sql server

Hi I have one doubt in sql server
get 0 when emptyornull values else max(id) when column datatype i is numeric in sql server
Table : empid
CREATE TABLE [dbo].[empid](
[id] [numeric](11, 0) NULL
) ON [PRIMARY]
GO
INSERT [dbo].[empid] ([id]) VALUES (NULL)
GO
INSERT [dbo].[empid] ([id]) VALUES (CAST(6 AS Numeric(11, 0)))
GO
based on above data I want output like below
id
6
I tried like below
select case when isnull( max(id),'')='' then cast (0 as numeric) else max(id end test from )
[Test].[dbo].[empid]
but above query is getting error
Msg 8114, Level 16, State 5, Line 9
Error converting data type varchar to numeric.
suppose no records in table then maxid will get 0
please tell me how to write a query to achive this task in sql server
You should use the COALESCE function that gives you the ability to replace a potential NULL with whatever you wish (0 in your current case) as so:
select coalesce(id, 0) as id from [dbo].[empid];
Why use ''? Just use 0:
SELECT ISNULL(id,0) AS test
FROM dbo.empid;
ISNULL returns the datatype of the first parameter, and with the SQL you had, you were therefore implicitly trying to convert '' to a numeric, which was failing.
The better way to do this is to use COALESCE function provided by SQL
COALESCE(arg1, arg2[, argN])
what it does is it takes N arguments
arg1 is a column that can be null
arg2 is a column that can be null
argN is the value that you want to replace it with
Query could be
SELECT COALESCE(Id, 0) as Id FROM [dbo].[empid]

Merge stored procedure with datatype conversions

I am able to execute my stored procedure. When I execute it a second time instead of updating the existing values same values from source are inserted as new values.
i.e my target has
1
2
3
When I run the stored procedure a second time, instead of updating 1,2,3, it is inserting the same
1
2
3
1
2
3
My condition for when matched then select S.REPORT_TEST1 except T.REPORT_TEST1 is not working.
When I use the same code on a different table which doesn't have data conversions I am able to update.
Can anyone tell where am I going wrong?
CREATE PROCEDURE [dbo].[Merge]
INSERT INTO .[dbo].[TARGET](REPORT_TEST1, REPORT_TEST2, REPOST_TEST3)
FROM (MERGE [dbo].[TARGET] T
USING (SELECT
Cast([REPORT TEST1] as int) [REPORT_TEST1],
Cast([REPORT TEST2] as int) [REPORT_TEST2],
Cast([REPORT TEST3] as int) [REPORT_TEST3]
FROM
[dbo].[SOURCE]) S ON (T.[REPORT_TEST1] = S.[REPORT_TEST1])
WHEN NOT MATCHED BY TARGET
THEN INSERT
VALUES (S.REPORT_TEST1, S.REPORT_TEST2, S.REPOST_TEST3)
WHEN MATCHED
AND EXISTS (SELECT S.REPORT_TEST1, S.REPORT_TEST2, S.REPOST_TEST3
EXCEPT
SELECT T.REPORT_TEST1, T.REPORT_TEST2, T.REPOST_TEST3)
OUTPUT $ACTION ACTION_OUT,
S.REPORT_TEST1, S.REPORT_TEST2, S.REPOST_TEST3) ;
Thanks
would it not suffice to rewrite your WHEN MATCHED statement thusly:
WHEN MATCHED
AND S.REPORT_TEST2 <> T.REPORT_TEST2
AND S.REPORT_TEST3 <> T.REPORT_TEST3
(
SELECT
S.REPORT_TEST1
,S.REPORT_TEST2
,S.REPOST_TEST3
)
I think I understand what you're trying to do, but inside the MERGE context, you're only comparing this row with that row, not the source row against the whole target table. you could modify the subselect thusly if you're trying to query "this source is not at all in the target"
WHEN MATCHED AND EXISTS
(
SELECT
S.REPORT_TEST1
,S.REPORT_TEST2
,S.REPOST_TEST3
EXCEPT SELECT
T2.REPORT_TEST1
,T2.REPORT_TEST2
,T2.REPOST_TEST3
FROM
[dbo].[TARGET] T2
)

How to pass a variable to a IN clause?

Lets say I have a SP that has a SELECT statements as follows,
SELECT product_id, product_price FROM product
WHERE product_type IN ('AA','BB','CC');
But data goes to that IN clause must be through a single variable that contains the string of values. Something link below
SELECT product_id, product_price FROM product
WHERE product_type IN (input_variables);
But its not working that way. Any idea how to do this?
Pass parameter value like this - 'AA,BB,CC'. Then, it is enough to use FIND_IN_SET function -
SELECT product_id, product_price
FROM product
WHERE FIND_IN_SET(product_type, param);
create a user-defined function that will convert the comma separated value into table, and by join this two can get the desired result.
for more
passing a string using a variable was a problem assume this solution
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `spTestListValues`(_list varchar(200))
BEGIN
SET #LIST=_list; -- assume this a paramter from the stored procedure
SELECT NULL AS Id, '' AS Description --insert null value to be used for list box population
UNION
(SELECT id, Description
FROM test_table
WHERE FIND_IN_SET(id,#LIST) ORDER BY Description ASC) ;
END
Calling the procedure from other query window
call `spTestListValues`('4,5,3'); --no paramter currently for test
output
ID Description
NUll
1 TEST1
4 TEST2
5 TEST3
Try using a prepared statement:
https://dev.mysql.com/doc/refman/8.0/en/sql-prepared-statements.html