want to apply transaction on below procedure but its not working - mysql

DELIMITER $$
USE `g4winners2`$$
DROP PROCEDURE IF EXISTS `ebetToTbConsumer`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `ebetToTbConsumer`()
BEGIN
START TRANSACTION;
INSERT INTO g4winners2.`tb_consumer`(first_name,middle_name,last_name,username,PASSWORD ,ssn,email,home_phone
,date_of_birth,gender_type,is_locked,is_active,is_online,bonus_level_id,modified_by_entity,modified_by_id,record_created_on,record_modified_on
,consumer_status_type
,business_id,driver_license,driver_license_state_provice,mothers_maiden_name,id_type,intl_id_state_code,id_expiration,id_status,COMMENT,reward_profile_id
,player_tracking_id
)
SELECT cont.first_name, cont.middle_initial, cont.last_name,cust.user_name, cust.encrypted_password, cust.social_security_number, cont.email,cont.home_phone,cust.birthdate,
cust.sex,
b'0',b'1',b'0',1,'3',1, FROM_UNIXTIME(cust.signup_date), FROM_UNIXTIME(cust.updated_date) ,cust.status,cust.business_id,cust.drivers_license,cust.drivers_license_state_province,cust.mothers_maiden_name,cust.id_type,cust.intl_id_state_code,
cust.id_expiration,cust.id_status,cust.comment,cust.reward_profile_id,cust.player_tracking_id
FROM ebet.`contact_info` cont ,ebet.`customer` cust WHERE cust.id=cont.customer_id ;
INSERT INTO `g4winners2`.`tb_consumer_address`(consumer_id,address_line_1,address_line_2
,city,state,zip_code,country,county,region,record_modified_on,mailing_list_flag,
funding_notification_flag,title,marketing1,partner_list_flag,company_name)
SELECT cont.customer_id, cont.address1,cont.address2,cont.city,cont.state_province,cont.postal_code,cont.country,cont.county,cont.suburb ,cont.updated_date, cont.mailing_list_flag,
cont.funding_notification_flag,cont.title,cont.marketing1,cont.partner_list_flag,cont.company_name FROM ebet.`contact_info` cont;
INSERT INTO g4winners2.tb_consumer_funds(tote_account_id,pin,total_available_fund,onhold_fund,tote_account_status,last_access)
SELECT acc.acct_number,acc.encrypted_pin, FLOOR(acc.current_balance),FLOOR(acc.hold_balance), acc.status,acc.last_access
FROM ebet.`account` acc;
INSERT INTO g4winners2.`tb_system_settings`(setting_id,setting_name,setting_value,business_id )
SELECT 0,conf.name,conf.value,conf.business_id FROM ebet.`config1` conf;
COMMIT;
END$$
DELIMITER ;

After creating the procedure, you need to run it. Have you tried to run it using
CALL ebetToTbConsumer(); ?
Your table g4winners2.tb_consumer contains some fields named with reserved words. PASSWORD, and COMMENT MUST be escaped when when using them in your table or you avoid them completely.
Also for g4winners2.tb_system_settings.setting_id field, make sure of the inserted value 0, if it would not throw some constraint error. You're better off if you take a look at the MySQL error log to really see what's going wrong.

You have to set the Server variable autocommit to OFF. You can set it globally bu adding it to server configuration file or explicitly set in procedure as below:
DELIMITER $$
USE `g4winners2`$$
DROP PROCEDURE IF EXISTS `ebetToTbConsumer`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `ebetToTbConsumer`()
BEGIN
SET autocommit=0; /******************Check this line******************/
START TRANSACTION;
INSERT INTO g4winners2.`tb_consumer`(first_name,middle_name,last_name,username,PASSWORD ,ssn,email,home_phone
,date_of_birth,gender_type,is_locked,is_active,is_online,bonus_level_id,modified_by_entity,modified_by_id,record_created_on,record_modified_on
,consumer_status_type
,business_id,driver_license,driver_license_state_provice,mothers_maiden_name,id_type,intl_id_state_code,id_expiration,id_status,COMMENT,reward_profile_id
,player_tracking_id
)
SELECT cont.first_name, cont.middle_initial, cont.last_name,cust.user_name, cust.encrypted_password, cust.social_security_number, cont.email,cont.home_phone,cust.birthdate,
cust.sex,
b'0',b'1',b'0',1,'3',1, FROM_UNIXTIME(cust.signup_date), FROM_UNIXTIME(cust.updated_date) ,cust.status,cust.business_id,cust.drivers_license,cust.drivers_license_state_province,cust.mothers_maiden_name,cust.id_type,cust.intl_id_state_code,
cust.id_expiration,cust.id_status,cust.comment,cust.reward_profile_id,cust.player_tracking_id
FROM ebet.`contact_info` cont ,ebet.`customer` cust WHERE cust.id=cont.customer_id ;
INSERT INTO `g4winners2`.`tb_consumer_address`(consumer_id,address_line_1,address_line_2
,city,state,zip_code,country,county,region,record_modified_on,mailing_list_flag,
funding_notification_flag,title,marketing1,partner_list_flag,company_name)
SELECT cont.customer_id, cont.address1,cont.address2,cont.city,cont.state_province,cont.postal_code,cont.country,cont.county,cont.suburb ,cont.updated_date, cont.mailing_list_flag,
cont.funding_notification_flag,cont.title,cont.marketing1,cont.partner_list_flag,cont.company_name FROM ebet.`contact_info` cont;
INSERT INTO g4winners2.tb_consumer_funds(tote_account_id,pin,total_available_fund,onhold_fund,tote_account_status,last_access)
SELECT acc.acct_number,acc.encrypted_pin, FLOOR(acc.current_balance),FLOOR(acc.hold_balance), acc.status,acc.last_access
FROM ebet.`account` acc;
INSERT INTO g4winners2.`tb_system_settings`(setting_id,setting_name,setting_value,business_id )
SELECT 0,conf.name,conf.value,conf.business_id FROM ebet.`config1` conf;
COMMIT;
END$$
DELIMITER ;

Related

mysql procedure with if condition

I'm in my first databases class and I'm trying to write a conditional block for a mysql procedure.
This is the procedure:
delimiter //
CREATE PROCEDURE add_ascent(IN cid INT, IN pid INT)
BEGIN
DECLARE count_ascents INT;
SET count_ascents = 0;
SELECT COUNT(`cid`) INTO count_ascents FROM ascents WHERE `cid`=cid AND `pid`=pid;
IF count_ascents < 1 THEN
INSERT INTO ascents (`cid`, `pid`) VALUES (cid, pid);
UPDATE climbers SET climbers.ascents = climbers.ascents + 1 WHERE climbers.id=cid;
UPDATE problems SET problems.ascents = problems.ascents + 1 WHERE problems.id=pid;
END IF;
END;
//
delimiter ;
The goal of the procedure is to only perform the insert and updates if the (cid, pid) pair is not in the the ascents database. After testing, the program doesn't seem to go into the if block at all.
FYI, you might want to consider using an UPSERT, instead of "select/if/insert". For example, mySQL offers INSERT ON DUPLICATE KEY UPDATE.
Here, I suggest:
giving your parameters a DIFFERENT name than the column name, for example iCid and iPid, then
Typing SELECT COUNT(cid) INTO count_ascents FROM ascents WHERE cid=iCid AND pid=iPid and checking the result.

user defined function in insert command

I created a function:
DELIMITER $$
DROP FUNCTION IF EXISTS `heena`.`customer_id`$$
CREATE DEFINER=`root`#`localhost` FUNCTION `heena`.`customer_id`(
a varchar(20),
b varchar(20)
) RETURNS varchar(50) CHARSET latin1
DETERMINISTIC
BEGIN
RETURN CONCAT(
(select ((id), 0) + 1
from heenaj),
substring(a,1,2),
substring(b,1,2));
END;$$
DELIMITER ;
The code executed fine, but when I'm inserting a value using:
insert into heenaj
(c_id,name,number)
values
(customer_id121("abcd",9868275817),"abcd",9868275817);
It shows an error:
Column 'c_id' cannot be null
There's something wrong with your RETURN.
Maybe you are meaning to do this, although I am only guessing:
RETURN CONCAT(
(select ifnull(max(id), 0) + 1
from heenaj),
substring(a,1,2),
substring(b,1,2));
sqlfiddle
Then, you're calling customerid121() not customer_id(). Could this be typo?
Also, in looking at what you're trying to do: do you want your id as auto_increment and just want to have c_id as the id, concatenated with first 2 characters of name and concatenated with first 2 characters of number?
I suggest another solution. It might be nicer to drop your function and create a TRIGGER for before INSERT, like this:
CREATE TRIGGER set_customer_id BEFORE INSERT on heenaj
FOR EACH ROW
BEGIN
SET NEW.c_id = CONCAT((SELECT IFNULL(MAX(id),0)+1 FROM heenaj),SUBSTRING(NEW.name,1,2),SUBSTRING(NEW.number,1,2));
END/
This way, when you insert you can just ignore c_id and insert like this:
insert into heenaj(name,number)
values ("abcd",9868);
The trigger will handle the setting of c_id for you.
sqlfiddle for TRIGGER
P.S. To create the trigger (in the sqlfiddle), I selected / as my delimiter. You might change that / to $$, since you're setting delimiter as $$.

Mysql said: #1422 - Explicit or implicit commit is not allowed in stored function or trigger

In the code below I'm trying to create a trigger which inserts 'incidentimg' table id along with an image path if the user of the web application did not upload a image with the form belonging to 'incidentreport' table, however, I'm only getting the error "MySQL said: #1422 - Explicit or implicit commit is not allowed in stored function or trigger"
DROP TRIGGER IF EXISTS `insertImage`;
CREATE TRIGGER `insertImage` AFTER INSERT ON `incidentreport`
FOR EACH ROW
BEGIN
IF(SELECT incidentimg.incidentImgId FROM incidentimg
LEFT JOIN incidentreport ON incidentimg.imgs_incidentReportId = incidentreport.incidentReportId
WHERE incidentimg.incidentImgId IS NULL)
THEN INSERT INTO incidentimg(incidentImgId, imgUrl)values(NEW.incidentReportId, 'images/no-image.png');
END IF;
END
;
Here are the tables being used
Can someone assist me on how to correct this problem
I finally got the code to work. Now the code will check whether 'incidentimg' table has all the 'incidentReportId' that the 'incidentreport' table has, and if it doesn't then the last inserted id from the 'incidentreport' table along with a default image path will be inserted into 'incidentimg' table AFTER INSERT.
CREATE TRIGGER insertImage AFTER INSERT ON incidentreport
FOR EACH ROW
BEGIN
IF(SELECT incidentreport.incidentReportId
FROM incidentreport
LEFT JOIN incidentimg ON incidentreport.incidentReportId = incidentimg.imgs_incidentReportId
WHERE incidentimg.imgs_incidentReportId IS NULL)
THEN INSERT INTO incidentimg(imgs_incidentReportId, imgUrl) VALUES(NEW.incidentReportId, 'images/no-image.png');
END IF;
END
I am not much sure but I am guessing that probably it's because of the IF .. THEN conditional INSERT. Try modifying your INSERT statement with an EXISTS like
DROP TRIGGER IF EXISTS `insertImage`;
CREATE TRIGGER `insertImage` AFTER INSERT ON `incidentreport`
FOR EACH ROW
BEGIN
INSERT INTO incidentimg(incidentImgId, imgUrl)
SELECT NEW.incidentReportId, 'images/no-image.png'
FROM DUAL WHERE EXISTS (
SELECT 1 FROM incidentimg
LEFT JOIN incidentreport
ON incidentimg.imgs_incidentReportId = incidentreport.incidentReportId
WHERE incidentimg.incidentImgId IS NULL
)
END;

MySQL trigger working on one table but not the other

I have created a mysql trigger to update on insert a value from another table:
DROP TRIGGER IF EXISTS `CourseCode`//
CREATE TRIGGER `CourseCode` BEFORE INSERT ON `race`
FOR EACH ROW BEGIN
SET NEW.Course_Code = (
SELECT
course_code
from
tb_course
where
tb_course.course_name = NEW.course_name
)
END
//
This works perfectly. It returns the 4 character code for the course_name based on the tb_course table.
What I'm trying to do is the exact same thing in another table, I copy and paste the trigger and rename the trigger and the table (field names and types are also identical) it but it won't work:
DROP TRIGGER IF EXISTS `CourseCode2`//
CREATE TRIGGER `CourseCode2` BEFORE INSERT ON `fields`
FOR EACH ROW
BEGIN
SET NEW.Course_Code = (
SELECT
course_code
from
tb_course
where
tb_course.course_name = NEW.course_name
)
END
//
However this results in null values. I've tried replacing New.Course_name with a string (i.e. tb_course.course_name="String") and that updates that static value fine so the trigger appears to be working but either it isn't matching the select statement in this table for or it's not setting the Course_Code field...
Is there any sort of debugging you can suggest to figure this out? It's driving me nuts and I don't know what to do to diagnose the problem.
Cheers
I have no idea what is wrong with the second trigger.
However, the 'debugging' part i can maybe help with.
A search of the 'net' will return various software (paid for) that will allow single step debugging. Rather than pay for stuff, all i want is 'print' statements from inside stored function procedures and triggers.
a quick search lead me to someone who has done all the work already.
Debugging Stored Procedures in MySql
I have just set it up in MySql and tried it and it works fine.
Here is some sample code, based on your trigger and the output i got.
DELIMITER $$
USE `testmysql`$$
DROP TRIGGER /*!50032 IF EXISTS */ `CourseCode`$$
CREATE
/*!50017 DEFINER = 'test'#'localhost' */
TRIGGER `CourseCode` BEFORE INSERT ON `race`
FOR EACH ROW BEGIN
DECLARE v_course_code INT;
DECLARE v_course_title VARCHAR(255);
CALL procLog("line 12: Entering CourseCode");
SELECT
course_code, course_title
INTO
v_course_code, v_course_title
FROM
tb_course
WHERE
tb_course.course_name = NEW.course_name;
SET NEW.course_code = v_course_code;
CALL procLog(CONCAT("line_22: ", v_course_title, " code: ", NEW.course_code));
CALL procLog("line 24: Exiting CourseCode");
END;
$$
DELIMITER ;
Query:
CALL setupProcLog();
INSERT INTO `race` (course_name, race_info)
VALUES ('learn_it_02', 'this is another test');
CALL cleanup('query end');
procLog output:
entrytime connection_id msg
2014-02-23 12:32:21 5 line 12: Entering CourseCode
2014-02-23 12:32:21 5 line_22: Learn It Course 02 code: 2
2014-02-23 12:32:21 5 line 24: Exiting CourseCode
2014-02-23 12:32:21 5 cleanup() query end
Ok, a little clumsy maybe but it will help with debugging 'stored' programs.
I will be using it from now on.

multiple value insert works in mysql procedures?

Multivalue insert example - it works manually but NOT in mySQL stored procedure.
INSERT INTO input_data1(mobile) VALUES (9619825525),(9619825255),(9324198256),(9013000002),(9999999450),(9999999876) ;
i am getting syntax error near "str" word in below proc, Can any one let me know how to implement this multi value INSERT work in procedure?
DELIMITER |
DROP PROCEDURE IF EXISTS mobile_series1;
CREATE PROCEDURE mobile_series1(IN str text)
LANGUAGE SQL READS SQL DATA
BEGIN
DROP TABLE IF EXISTS input_data1 ;
CREATE TEMPORARY TABLE input_data1 (mobile varchar(1000)) engine=memory;
INSERT INTO input_data1(mobile) VALUES str;
END |
DELIMITER ;
Thanks in Advance.
I don't have a MySQL server so there's probably syntax errors and +1 errors (i.e. may not be capturing the last on the list, may not progress past the first item etc, problems fixed by putting a +1 in the code), but you basically want to replace your INSERT statement with something this.
DECLARE INT _CURSOR 0;
DECLARE INT _TOKENLENGTH 0;
DECLARE VARCHAR _TOKEN NULL;
SELECT LOCATE(str, ",", _CURSOR) - _CURSOR INTO _TOKENLENGTH;
LOOP
IF _TOKENLENGTH <= 0 THEN
SELECT RIGHT(str, _CURSOR) INTO _TOKEN;
INSERT INTO input_data1(mobile) VALUE _TOKEN;
LEAVE;
END IF;
SELECT SUBSTRING(str, _CURSOR, _TOKENLENGTH) INTO _TOKEN;
INSERT INTO input_data1(mobile) VALUE _TOKEN;
SELECT _CURSOR + _TOKENLENGTH + 1 INTO _CURSOR;
SELECT LOCATE(str, ",", _CURSOR + 1) - _CURSOR INTO _TOKENLENGTH;
END LOOP;
Your function call would then be something like
EXEC mobile_series1('9619825525,9619825255,9324198256')