MySQL stored procedure is not working - mysql

I am new to Mysql. I have a stored procedure,below is my SP
CREATE DEFINER=`root`#`localhost` PROCEDURE `insertGroup`(IN startdate date,
IN enddate date,
IN amount int,
IN groupname char(50))
BEGIN
DECLARE c_id INT;
set c_id =(select id from c_begin where startdate = startdate and enddate = enddate and amount = amount);
insert into c_group (c_beginid,Groupname)
select * from (select c_id,groupname) as temp
where not exists (
select c_beginid,groupname from c_group where c_beginid = c_id and groupname = groupname
) ;
END
I am calling it like
call insertGroup ('2014-01-01','2015-12-31',100000,'GroupD');
But it is not inserting any row. I am trying to insert into "c_group" if the c_beginid and groupname is not exists.
But when i try like below
insert into c_group (c_beginid,Groupname)
select * from (select 1,'GroupD') as temp
where not exists (
select c_beginid,groupname from c_group where c_beginid = 1 and groupname = 'GroupD'
) limit 1 ;
it is working.
So What went wrong in my "insertGroup" SP. Can any one help me ?
Thanks ,

Rename your input parameter to make it clear to the DB engine when you mean the parameter and when the column name.
where startdate = startdate and enddate = enddate and amount = amount
is always true since the engine thinks you compare a column to itself.

Related

the value doesn't show on the sp

I tried a simple app for testing but doesn't get the value on my table.
what I am doing wrong?
I want just put a value in a variable (not default) and then from the variable put it on the table.
like so
CREATE DEFINER=`mysql`#`localhost`
PROCEDURE `calcularferiado`(
in StartDate date,
in EndDate date,
in Duration int)
BEGIN
DECLARE DateDiff1 Int;
SELECT DateDiff1 = DATEDIFF(StartDate,EndDate);
INSERT INTO my_schema.feriados(inicio,fin,activo)
values (StartDate, EndDate, DateDiff1);
END
SEt DateDiff1 = DATEDIFF(StartDate,EndDate);
not
SElect DateDiff1 = DATEDIFF(StartDate,EndDate);

Create function on mysql

I have the following on mysql:
DELIMITER //
CREATE FUNCTION dateDiff1(contract_id INT, cust_id INT)
RETURNS INT
BEGIN
DECLARE startDate, endDate DATETIME;
DECLARE result int;
SET startDate = (SELECT startDate FROM contract WHERE insurance_cover_id = contract_id AND customer_id = cust_id);
SET endDate = (SELECT endDate FROM contract WHERE insurance_cover_id = contract_id AND customer_id = cust_id);
SET result = (SELECT TIMESTAMPDIFF(MONTH, endDate, startDate));
RETURN result;
END;
//
DELIMITER ;
SELECT dateDiff1(1,1);
and it returns NULL, any suggestion?
Maybe, you could solved your issue as follows as far as you got some data in your database:
CREATE FUNCTION datediff1(_contract_id INT [, _cust_id INT])
RETURNS INT DETERMINISTIC
BEGIN
DECLARE res INT;
SELECT TIMESTAMPDIFF(MONTH, endDate, startDate) FROM contract WHERE contract_id =
_contract_id [AND cust_id = _cust_id] INTO res;
RETURN res;
END
I marked the cust_id related parts as optional since it is most likely that you contract_id is already referred to a particular customer.
I hope it will help. Good luck.

Issue to execute mysql stored procedure file in phpmyadmin

I have a stored procedure in mySQL when running script in phpmyadmin it give syntax error. When create manually it execute.Anyhelp would be appreciated
It shows error when i run through SQL Query when I do manually phpmyadmin stored procedure function it create it
CREATE PROCEDURE `sp_ConsolidatedFollowFeedUserList`(
_uid INT,
_startTime INT,
_endTime INT,
_activityType VARCHAR(150),
`_follow_to` INT,
`_offset` INT,
`_limit` INT
)
BEGIN
SELECT
feed.id `feed_id`,
activity.id ` activity_id`,
activity.uid AS `uid`,
activity.source_id AS follow_to,
activity.activity_type,
activity.source_id,
activity.parent_id,
activity.parent_type,
activity.post_id
FROM
`user_feed` feed
JOIN user_activity activity ON feed.activity_id = activity.id
WHERE
feed.uid = _uid
AND feed.`status` = 'ACTIVE'
AND activity.`status` = 'ACTIVE'
AND activity.activity_type IN(_activityType)
AND activity.created BETWEEN startTime AND endTime
AND activity.source_id = _follow_to
ORDER BY
activity.created DESC
LIMIT
offset, limit;
END
If your stored procedure is in a file, then you don't need the `` to protect the column fields. Then your parameter names have to match exactly offset is not matching _offset.
CREATE PROCEDURE `sp_ConsolidatedFollowFeedUserList`(
_uid INT,
_startTime INT,
_endTime INT,
_activityType VARCHAR(150),
_follow_to INT,
_offset INT,
_limit INT)
BEGIN
SELECT
feed.id AS feed_id,
activity.id AS activity_id,
activity.uid AS uid,
activity.source_id AS follow_to,
activity.activity_type,
activity.source_id,
activity.parent_id,
activity.parent_type,
activity.post_id
FROM
user_feed AS feed
JOIN user_activity activity ON feed.activity_id = activity.id
WHERE
feed.uid = _uid
AND feed.status = 'ACTIVE'
AND activity.status = 'ACTIVE'
AND activity.activity_type IN (_activityType)
AND activity.created BETWEEN _startTime AND _endTime
AND activity.source_id = _follow_to
ORDER BY activity.created DESC
LIMIT _offset, _limit;
END

Stored Procedure Can't drop temp table it don't exist

SQL Server 2008
This is a continuation of my last question. Now I'm trying to create a stored procedure, however I can't execute it. When I execute it, an error message displays
"Cannot drop the table #MyReport", because it does not exist or you do not have permissions.
Please guide me in the right direction.
Below is my stored Procedure
Create PROCEDURE [dbo].[SEL_MyReport]
(
#employeeid int,
#date1 datetime,
#date2 datetime
)
AS
BEGIN
drop table #MyReport
Create Table #MyReport
(
employeeid int,
name varchar(30),
department varchar(30),
checkTime datetime
)
if (#employeeid > 0)
Begin
INSERT INTO #MyReport (employeeid,name, department, checkTime)
select emp.EmpolyeeID, emp.Name,dep.DeptName,tm.checkTime
from TimeInOut tm
left join Employee emp on emp.EmpolyeeId = tm.EmployeeId
left join Department dep on dep.DeptID = emp.defaultDeptID
where (DATEDIFF(s,#date1,tm.checktime) >=0
and DATEDIFF(s,#date2,tm.checktime)<=0) and emp.employeeID = #employeeid
SELECT
employeeid
,name
,department
,[Time In] = MIN(checkTime)
,[Time Out] = MAX(checkTime)
FROM #MyReport
GROUP BY employeeid,name, department, CAST(checktime AS DATE)
End
Else
Begin
INSERT INTO #MyReport (employeeid,name, department, checkTime)
select emp.EmpolyeeID, emp.Name,dep.DeptName,tm.checkTime
from TimeInOut tm
left join Employee emp on emp.EmpolyeeId = tm.EmployeeId
left join Department dep on dep.DeptID = emp.defaultDeptID
where (DATEDIFF(s,#date1,tm.checktime) >=0
and DATEDIFF(s,#date2,tm.checktime)<=0)
SELECT
employeeid
,name
,department
,[Time In] = MIN(checkTime)
,[Time Out] = MAX(checkTime)
FROM #MyReport
GROUP BY employeeid,name, department, CAST(checktime AS DATE)
End
END
Go
exec SEL_MyReport('639','05/01/2014','05/08/2014')
There is quite a bit I would change - here is the code.
You will notice
branching logic (if #employeeid > 0) has been replaced by a slightly more verbose WHERE clause
no need for #tables as far as I can tell, the SELECT should suffice
Unfortunately, I do not have anything to test against, but you should understand the general impression of it.
Further, your date filtering seemed quite strange, so I assumed you may have meant something else - I could be mistaken. Either way, the way the date filtering is now done is SARGable
CREATE PROCEDURE [dbo].[SEL_MyReport]
(
#employeeid INT,
#date1 DATETIME,
#date2 DATETIME
)
AS
BEGIN
SET NOCOUNT ON;
SELECT emp.EmpolyeeID
,emp.Name
,dep.DeptName
,[Time In] = MIN(tm.checkTime)
,[Time Out] = MAX(tm.checkTime)
FROM TimeInOut tm
LEFT
JOIN Employee emp on emp.EmpolyeeId = tm.EmployeeId
LEFT
JOIN Department dep on dep.DeptID = emp.defaultDeptID
WHERE tm.checktime >= #date1
AND tm.checktime <= #date2
/***********************************************************************************************************
* I've assumed what you may be trying to express, above
* You might also want to look at the BETWEEN() operator, remembering that it is inclusive in its behaviour
* (DATEDIFF(s,#date1,tm.checktime) >=0
* AND DATEDIFF(s,#date2,tm.checktime)<=0)
***********************************************************************************************************/
AND (emp.employeeID = #employeeid OR #employeeid <= 0)
GROUP BY emp.EmpolyeeID, emp.name, dep.department, CAST(tm.checktime AS DATE)
END
GO
Well, since the very first step of your Stored Procedure attempts to drop a table, this will obviously result in an error if that table does not exist.
To work around this, make sure you check whether the table exists, before you drop it:
IF OBJECT_ID('tempdb..#MyReport') IS NOT NULL DROP
TABLE #MyReport

MySQL insert trigger with multiple inserts at the same time

I'm trying to generate a primary key for my table, something like this
(simplified version) - the purpose is to have a daily incremented key:
DELIMITER ^
CREATE TABLE `ADDRESS` (
ID INTEGER NOT NULL DEFAULT -1,
NAME VARCHAR(25),
PRIMARY KEY(`ID`))^
CREATE FUNCTION `GETID`()
RETURNS INTEGER
deterministic
BEGIN
declare CURR_DATE DATE;
declare maxid, _year, _month, _day, newid INTEGER;
set CURR_DATE = CURRENT_DATE;
set _year = EXTRACT(YEAR FROM CURR_DATE);
set _mon = EXTRACT(MONTH FROM CURR_DATE);
set _day = EXTRACT(DAY FROM CURR_DATE);
set newid = (_year - (_year/100) * 100) * 10000 + _mon * 100 + _day;
select max(ID) into maxid From `ADDRESS`;
if (maxid is null) then
set maxid = 0;
end if;
if (MAXID / 1000 != newid) then
set MAXID = newid * 1000;
end if;
set MAXID = MAXID + 1;
return MAXID;
END^
CREATE TRIGGER `ADDRESS_ID_TRIGGER` BEFORE INSERT ON `ADDRESS`
FOR EACH ROW
BEGIN
if new.id=-1 then
set new.id = getid();
end if ;
END^
COMMIT^
DELIMITER ;
Generally it works fine, but when I test it with multiple inserts at the same time
it obviously fails (e.g. no dirty reads, the select max will fail for the 2nd insert,
thus it will generate the same id as fro the 1st insert).
Workaround:
Make primary key AUTO_INCREMENT.
Add TIMESTAMP field and use BEFORE INSERT/UPDATE trigget to set CURRENT_TIMESTAMP().
Also you can use ON UPDATE CURRENT_TIMESTAMP option for TIMESTAMP field, value will be updated automatically.
So, ID is ID, and TIMESTAMP field contains date and time.