this should be working but I get an error somehow. I want to get the credits column from the table and multiply it by 100. The problem is to get the number of credits for a given student id and year and get the total payment. Assuming each credit is $100.
delimiter //
create function fTest (stuYear varchar(4), stuID varchar(4))
returns varchar(200)
begin
declare msg varchar(200) default '';
if (stuYear = '' or stuYear is null) then
select 'Please input a valid year' into msg;
elseif (stuID = '' or stuID is null) then
select 'Please input a student id' into msg;
else
begin
if (msg = '' or msg is null) then
select ('No result found for student ID: ', stuID, ' at year: ', stuYear) into msg;
select (credits * 100) into msg from Students_Courses natural join Courses where sid=stuID and year=stuYear group by credits;
return msg ;
end if;
end ;
end if;
end ;
//
delimiter ;
This is incorrect:
select ('No result found for student ID: ', stuID, ' at year: ', stuYear)
A select statement can contain multiple columns, but you shouldn't enclose them in parentheses. Also, that would return multiple values, which you can't select into a single message.
So, I guess you wanted to concat the values into a single value. You can do that using the concat function, like so:
select concat('No result found for student ID: ', stuID, ' at year: ', stuYear)
Btw, a normal assignment using the concat function should also work in a trigger:
SET msg = concat('No result found for student ID: ', stuID, ' at year: ', stuYear);
See MySQL concat function
PS: In the next statement, you also got parentheses: (credits * 100)
In this case it accidentally will work, because it's a single expression. They don't have any functional value, though, and might as well be removed.
Related
I have a Stored Procedure that takes three parameters, one of which is TEXT and it should contain comma separated values with ids, something like this -> '12345,54321,11111,22222', and this it inserts a row with data for each id in the list. Below is the Stored Procedure:
DELIMITER //
-- Create Stored Procedure
CREATE PROCEDURE MyProcedure(
IN ItemUUID VARCHAR(255),
IN ReceiverIds TEXT,
IN ItemCreated VARCHAR(255)
)
BEGIN
DECLARE strLen INT DEFAULT 0;
DECLARE SubStrLen INT DEFAULT 0;
IF ReceiverIds IS NULL THEN
SET ReceiverIds = '';
END IF;
do_this:
LOOP
SET strLen = LENGTH(ReceiverIds);
INSERT INTO item_receiver (item_uuid, receiver_id, item_created)
VALUES (ItemUUID ,SUBSTRING_INDEX(ReceiverIds, ',', 1),ItemCreated);
SET SubStrLen = LENGTH(SUBSTRING_INDEX(ReceiverIds, ',', 1)) + 2;
SET ReceiverIds = MID(ReceiverIds, SubStrLen, strLen);
IF ReceiverIds = '' THEN
LEAVE do_this;
END IF;
END LOOP do_this;
END//
DELIMITER ;
To get comma separated values with ids, something like this -> '12345,54321,11111,22222' I execute subquery, however, when I call this Stored Procedure I get this error -> Error Code: 1242. Subquery returns more than 1 row
SET group_concat_max_len = 2048;
call MyProcedure('random_test_uuid',(
SELECT CAST(GROUP_CONCAT(receiver_id SEPARATOR ',') AS CHAR) AS receiver_ids FROM receiver
WHERE user_id LIKE (SELECT user_id FROM user WHERE user_name LIKE 'myName')
GROUP BY receiver_id ),
'2017-09-24 23:44:32');
The problem is the subquery. Remove the group by:
SELECT CAST(GROUP_CONCAT(receiver_id SEPARATOR ',') AS CHAR) AS receiver_ids
FROM receiver
WHERE user_id LIKE (SELECT user_id FROM user WHERE user_name LIKE 'myName')
With the group by, you are getting a separate row for each receiver_id. The group_concat() is not doing anything.
Also, the CAST() is unnecessary. And this would typically be written as:
SELECT GROUP_CONCAT(r.receiver_id SEPARATOR ',') AS receiver_ids
FROM receiver r JOIN
user u
ON u.user_id = r.user_id
WHERE u.user_name LIKE 'myName';
If 'myName' is not using wildcards, then = is more appropriate than like.
If receiver_id is not unique in receiver, then you might want to add distinct to the group_concat().
I have one procedure in my MySQL Database.
My procedure working fine. But currently I have to set order by tblUserKeyStatus.createdDate inside IF (opt=1) condition and when I set order by, It gives me the following error
Error Code: 1054. Unknown column 'tblUserKeyStatus.createdDate' in 'order clause
My Stored Procedure is given below
CREATE PROCEDURE proc_GetStatus(IN _userId varchar(64) , IN _qtr int, IN opt int)
BEGIN
IF (opt = 1) then
SELECT tblKeyStatus.*,'pending' AS `Status`,'' as scheduleDate,
' ' as doneDate,' ' as result FROM tblUserKeyStatus,tblKeyStatus WHERE tblKeyStatus.trimId not in
(SELECT trimId from tblUserKeyStatus WHERE userId=_userId)
union
SELECT tblKeyStatus.*,tblUserKeyStatus.`Status` AS `Status`,tblUserKeyStatus.scheduleDate,
tblUserKeyStatus.doneDate,tblUserKeyStatus.result FROM tblKeyStatus,tblUserKeyStatus WHERE
tblUserKeyStatus.trimId=tblKeyStatus.trimId and tblUserKeyStatus.userId=_userId
order by tblUserKeyStatus.createdDate;
Else
SELECT * from tblKeyStatus WHERE qtr=_qtr;
End if;
END
ORDER BY is applied to the whole query specified in the UNION operation, so that the entire result set returned by UNION is ordered.
Try to select createdDate field in both subqueries, so that it is accessible to ORDER BY:
SELECT tblUserKeyStatus.createdDate,
tblKeyStatus.*,'pending' AS `Status`,
'' as scheduleDate,
' ' as doneDate,
' ' as result
FROM tblUserKeyStatus, tblKeyStatus
WHERE tblKeyStatus.trimId not in (SELECT trimId
from tblUserKeyStatus
WHERE userId=_userId)
UNION
SELECT tblUserKeyStatus.createdDate,
tblKeyStatus.*,
tblUserKeyStatus.`Status` AS `Status`,
tblUserKeyStatus.scheduleDate,
tblUserKeyStatus.doneDate,tblUserKeyStatus.result
FROM tblKeyStatus,tblUserKeyStatus
WHERE tblUserKeyStatus.trimId=tblKeyStatus.trimId and
tblUserKeyStatus.userId=_userId
ORDER BY createdDate;
You also have to remove the tblUserKeyStatus name prefix.
Try having braces for select
CREATE PROCEDURE proc_GetStatus(IN _userId varchar(64) , IN _qtr int, IN opt int)
BEGIN
IF (opt = 1) then
SELECT tblKeyStatus.*,'pending' AS `Status`,'' as scheduleDate,
' ' as doneDate,' ' as result FROM tblUserKeyStatus,tblKeyStatus WHERE tblKeyStatus.trimId not in
((SELECT trimId from tblUserKeyStatus WHERE userId=_userId)
union
(SELECT tblKeyStatus.*,tblUserKeyStatus.`Status` AS `Status`,tblUserKeyStatus.scheduleDate,
tblUserKeyStatus.doneDate,tblUserKeyStatus.result FROM tblKeyStatus,tblUserKeyStatus WHERE
tblUserKeyStatus.trimId=tblKeyStatus.trimId and tblUserKeyStatus.userId=_userId
order by createdDate));
Else
SELECT * from tblKeyStatus WHERE qtr=_qtr;
End if;
END
I have this records from my users table:
user_id first_name last_name gender email
******* ********** ********* ****** *****
229 Natalie Fern F natalie.fern#hotmail.com
and I want to search same First Name & Last Name from first_name OR last_name.
I have created sql query but not getting record.
SELECT *
FROM user_detail
WHERE first_name LIKE '%Natalie Fern%'
OR last_name LIKE '%Natalie Fern%'
LIMIT 0 , 30
You notice that I am passing first & last name from both fields.
Any Idea why I am not getting records?
Thanks.
You are using the LIKE operator for first_name and last_name as follows:
LIKE '%Natalie Fern%'
This will only match strings which contain anything followed by 'Natalie Fern' followed by anything. But since the first and last name columns only contain (surprise) the first and last names, your query isn't matching any records. You can use CONCAT to try to match the combination of first and last names:
SELECT *
FROM user_detail
WHERE CONCAT(first_name, ' ', last_name)
LIKE '%Natalie Fern%'
LIMIT 0, 30
If you want to check for people whose first or last names could be 'Natalie' or 'Fern', then you could use this query:
SELECT *
FROM user_detail
WHERE first_name LIKE '%Natalie%'
OR first_name LIKE '%Fern%'
OR last_name LIKE '%Natalie%'
OR last_name LIKE '%Fern%'
LIMIT 0, 30
You get no records because no column contains somethink like "Natalie Fern".
You have to concat both columns and you should get the correct result.
But concatination of columns is not a standard. So you have to look in the documantation of your DBMS.
Here some examples:
MySQL: CONCAT( )
Oracle: CONCAT( ), ||
SQL Server: +
Try this
Sql Fiddle
Function
CREATE FUNCTION [dbo].[fn_Split](#text varchar(8000), #delimiter varchar(20))
RETURNS #Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE #index int
SET #index = -1
WHILE (LEN(#text) > 0)
BEGIN
SET #index = CHARINDEX(#delimiter , #text)
IF (#index = 0) AND (LEN(#text) > 0)
BEGIN
INSERT INTO #Strings VALUES (#text)
BREAK
END
IF (#index > 1)
BEGIN
INSERT INTO #Strings VALUES (LEFT(#text, #index - 1))
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
ELSE
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
RETURN
END
Query
SELECT * FROM user_detail inner join
(select value from fn_split('Natalie Fern',' ')) as split_table
on (user_detail.first_name like '%'+split_table.value+'%'
or user_detail.last_name like '%'+split_table.value+'%' ;
instead of LIKE you can use LOCATE to see if the first name is in a string
SELECT *
FROM user_detail
WHERE LOCATE(first_name,'Natalie Fern') > 0
OR LOCATE(last_name ,'Natalie Fern') > 0
LIMIT 0 , 30
If you need to perform this search with one search input field:
SELECT *
FROM user_detail
WHERE last_name LIKE '%###VALUE###%'
OR first_name LIKE '%###VALUE###%'
OR concat(last_name, ' ', first_name) LIKE '%###VALUE###%'
OR concat(first_name, ' ', last_name) LIKE '%###VALUE###%';
I would like to retrieve all data from table in MySQL if column value providing null value?
I have a table like country.
How to write a query
If country = ' ' I need to display all data in table.
If country='algeria', it will display the particular data.
I need both queries in a single query.
i am getting result .but without providing variable how to write query...
declare #country1 varchar(30)
set #country1 = 'asd'
SELECT country_id, country
FROM country
WHERE ((#country1 = '') or (#country1 != '' and country.country= #country1));
nulls are different than empty strings (''), and should be checked explicitly with the is operator.
Assuming the variable you're passing is :country:
SELECT country_id, country
FROM country
WHERE (:country IS NULL) or (:country = country.country)
If you have an input like :country:
select
country.country_id, country.country
from
country
where
country.country = case when TRIM(:country) = '' or :country IS NULL then country.country else :country end
DELIMITER $$
CREATE PROCEDURE sp1 (x VARCHAR(30))
BEGIN
SELECT
country.country_id, country.country
FROM
country
WHERE
country.country = CASE WHEN TRIM(x) = '' OR x IS NULL THEN country.country ELSE x END;
END;
$$
DELIMITER ;
call sp1('COUNTRY');
I'm doing a nested case. However, I am getting an error near this line:
else
select concat('The month parameter ', p_month, ' is invalid; cannot proceed.');
This is actually the else case for the most inner case. p_month is an IN parameter and also an integer. Could this be the error?
Any thoughts will be helpful. Thank you.
I played around with it a little bit more right now. So I decided to SELECT on the outside block. However, I know now I have an error for the Select statement in the inner block. How can I fix that? Thanks.
entire code:
Create procedure ExamFeesMonth(in p_cl_id int, in p_month int)
begin
declare count_cl_id int;
declare num_exam int;
declare count_exam int;
declare v_msg varchar(200);
-- check if p_cl_id is in vt_clients
select count(*) into count_cl_id from vt_clients where cl_id = p_cl_id;
-- count the number of exams that has happened in p_month of previous year
select count(*) into num_exam
from vt_clients cl
join vt_headers h on cl.cl_id = h.cl_id
join vt_details d on h.ex_id = d.ex_id
where cl.cl_id = p_cl_id
and month(ex_date) = p_month
and year(ex_date) = (year(current_date())-1)
;
select
-- first case block starts
case
-- client valid
when count_cl_id = 1 then
-- second case block starts
case
-- p_month valid
when p_month in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) then
-- third case block starts
case
-- existing exams
when count_exam >= 1 then
select concat( 'Client ', p_cl_id, ' has ', count(h.ex_id),
' exam(s) with total fees of ', sum(ex_fee),
' in ', year(current_date())-1, '-', p_month)
from vt_clients cl
join vt_exam_headers h on cl.an_id = h.an_id
join vt_exam_details d on h.ex_id = d.ex_id
where cl_id = p_cl_id
and year(ex_date) = (year(current_date())-1)
and month(ex_date) = p_month
;
-- no exams
when count_exam = 0 then
concat( 'No exams for client ', p_cl_id, ' in 2011-' , p_month, '.');
-- third case block ends
end
-- p_month invalid
else
concat('The month parameter ', p_month, ' is invalid; cannot proceed.');
-- second case block ends
end
-- client invalid
when count_cl_id = 0 then
concat('We have no client with id ', p_cl_id, '; cannot proceed.') ;
-- first case block ends
end case;
end;
#
I think the issue in END statements in the nested CASEs. You should use END CASE. CASE...END CASE
-- third case block ends
end case; -- <-------------here
-- p_month invalid
else
concat('The month parameter ', p_month, ' is invalid; cannot proceed.');
-- second case block ends
end case; -- <-------------and here