MySQL stored procedure character encoding - mysql

I've been experiencing a rather annoying issue, when inserting data into a MySQL database table, using a stored procedure. The database, made in MySQL Workbench 6.3, has characters in tables defined as utf8, and it works perfectly well, but insertion into the tables by stored procedures, changes the character encoding, leaving wrong characters instead of the correct ones. I've been looking all over for an answer. Hope someone can help. Thanks !
delimiter $$
use lfms_browser$$
drop procedure if exists spAddMember$$
create procedure spAddMember
(
in member varchar(60) character set utf8,
in city varchar(60) character set utf8
)
begin
insert into Members
(
member,
city
)
values
(
member,
city
)
;
end$$
delimiter ;

Related

How to Create Stored Procedure in MySQL

My tables are
create table employee(
id int(10) auto_increment primary key,
name varchar(100),
addressId int(10)
);
go
create table address(
id varchar(10) auto_increment primary key,
name varchar(100)
);
Here is my procedure
create procedure insert_employee(IN emp_name varchar(100),IN emp_address varchar(100))
begin
DECLARE #addressId varchar(10);
SELECT #addressId:=id from address where name LIKE '%'+emp_address+'%';
IF #addressId = ''
THEN
set #addressId= 'DBS-2136';-- It will come form function
INSERT INTO address values(#addressId,emp_address);
END IF
INSERT INTO employee values(emp_name,#addressId);
END
I don't understand what is the problem. If i write this type of if condition in ms sql server there is not error. every time execute the procedure ti say error in end if. I have search in google but there is not idea about this. there is a problem in declare variable. If i copy form mysql documentation that also not work. why is that?
please help me
1. What is the proper way to declare variable under mysql stored procedure,
2. how to write if condition in mysql stored procedure.
thank you
Lots of differences between mysql and mssql. Declared variables should not include '#', all statements must be terminated, + is an arithmetic operator, if you procedure has multiple statements you must set delimiters before and after.
Further reading
How to declare a variable in MySQL?
https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html
From MySQL reference Manual
An IF ... END IF block, like all other flow-control blocks used within stored programs, must be terminated with a semicolon
IF #addressId = ''
THEN
set #addressId= 'DBS-2136';-- It will come form function
INSERT INTO address values(#addressId,emp_address);
END IF;

Stored procedures that dont work?

I am trying to create some stored procedures in my database for my assignment and I can't work out why they don't work correctly as they run, they just don't have the desired effect.
The first is attempting to add members to my table. It runs fine but nothing is added. It just add's 0's for everything.
CREATE DEFINER=`root`#`localhost` PROCEDURE `AddMember`(IN `iFirstname` VARCHAR(15) CHARSET utf8, IN `iLastname` VARCHAR(15) CHARSET utf8, IN `iCPR` INT(10) ZEROFILL, IN `iPhone` INT(8) ZEROFILL, IN `iAddress` VARCHAR(50) CHARSET utf8, IN `iPostcode` INT(4) UNSIGNED, IN `iDateJoined` DATE, IN `iNewsletter` BOOLEAN)
MODIFIES SQL DATA
SQL SECURITY INVOKER
INSERT INTO members (FirstName,
LastName,
CPR,
PhoneNumber,
Address,
Postcode,
DateJoined,
Newsletter)
VALUES (iFirstname,
iLastname,
iCPR,
iPhone,
iAddress,
iPostcode,
iDateJoined,
iNewsletter)
The second is deleting a member. If I run the DELETE FROM WHERE line by it's self it works fine but when its put into the stored procedure it doesn't work.
CREATE DEFINER=`root`#`localhost` PROCEDURE `DeleteMember`(IN mID INT)
BEGIN
DELETE FROM members WHERE MemberID = mID;
END
I am a bit confused as to what is wrong with them as I am new to this and finding specific answers is difficult especially as most examples are even more complex.
Hello Create an id Field in database table with auto incremented values then you will be able to store values via Stored Procedure returned above

MariaDB will not change the collation for a database

I have been researching this problem on StackOverflow for more than 24 hours and decided that this isn't already covered elsewhere even though there are many Q&A about the same topic.
I am using HeidiSQL 9.3 against MariaDB 10.1 and have a strange problem as follows: I originally accepted the default collation when I created my database then realized that this wasn't what I wanted and tried to change it with
ALTER DATABASE InternalFulfillment CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
This has no effect, and the database is still reported as ucs2_bin and all of the procedures and functions are ucs2_bin as well. I tried all of the advice from every Q&A I could find on StackOverflow including these statements:
SET collation_connection = 'utf8mb4_unicode_ci';
SET NAMES 'utf8mb4';
SET CHARACTER SET 'utf8mb4';
When I drop and recreate the procedures they still come back as ucs2_bin.
The strangest thing of all is that if I drop and recreate the database with the name 'InternalFulfilment' the collation is wrong, but if I create a database with a different name then I get the collation I want, and running the script that creates the stored procedures creates procedures with the utf8mb4_unicode_ci collation.
It seems like MariaDB and/or HeidiSQL is remembering the original collation that I used when I first created the 'InternalFulfillment' database, and always uses ucs2_bin collation whenever I create a database with this name.
Does anyone have any idea where this might be stored so I can clear it. Thanks.
Additional comments after reading answers below
After leaving this overnight, the next morning I was able to drop and recreate the database with a different collation, but now it is stuck on the new collation.
Following on from the answer from #Anse:
DROP DATABASE IF EXISTS `InternalFulfillment`;
CREATE DATABASE `InternalFulfillment` /*!40100 COLLATE 'ucs2_bin' */;
USE `InternalFulfillment`;
CREATE TABLE `table1` (
`column1` VARCHAR(50) NULL
)
COLLATE='ucs2_bin'
ENGINE=InnoDB;
DELIMITER //
CREATE DEFINER=`root`#`%` PROCEDURE `proc1`(IN `param1` VARCHAR(50))
DETERMINISTIC
BEGIN
SELECT
column1
FROM
table1 t
WHERE
t.column1 = param1;
END//
DELIMITER ;
CALL proc1('test');
Produces: /* SQL Error (1267): Illegal mix of collations (ucs2_bin,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '=' */. If I re-run this script with utf8mb4_general_ci then it completes without error.
Yesterday my database was stuck in ucs2_bin and today it is stuck in utf8mb4_general_ci so there is something that is cached with a fairly long expiry time.
Looks like there is some collation cache in MariaDB. I'm the author of HeidiSQL, and I'm pretty sure there is no such collation cache thing in HeidiSQL itself, so it must be a MySQL and/or MariaDB issue.
However, I just tried to reproduce the issue on a MySQL v5.7.9 server on my local Windows, without luck:
CREATE DATABASE `InternalFulfillment` /*!40100 COLLATE 'ucs2_bin' */;
CREATE TABLE `table1` (
`Column 1` VARCHAR(50) NULL
)
COLLATE='ucs2_bin'
ENGINE=InnoDB;
Both the database and table1 have ucs2_bin collation, as expected.
ALTER DATABASE `internalfulfillment` COLLATE 'utf8mb4_general_ci';
CREATE TABLE `table2` (
`Column 1` VARCHAR(50) NULL
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB;
Now, the database and the newly created table2 report the changed collation, as expected:
SELECT `DEFAULT_COLLATION_NAME` FROM `information_schema`.`SCHEMATA`
WHERE `SCHEMA_NAME`='internalfulfillment';
>> utf8mb4_general_ci
SELECT TABLE_NAME, TABLE_COLLATION FROM `information_schema`.`TABLES`
WHERE TABLE_SCHEMA='internalfulfillment';
TABLE_NAME | TABLE_COLLATION
table1 | ucs2_bin
table2 | utf8mb4_general_ci
So, my guess is that you have hit a bug in MariaDB.
Check these:
SHOW VARIABLES LIKE 'char%'; -- If anything say 'ucs2...', you should change it
SHOW CREATE DATABASE ...; -- The /*!40100 */ 'comment' is for hiding the clause for old versions.
SHOW CREATE PROCEDURE ...\G
Some basics (which you seem to already understand):
The CHARACTER SET and COLLATION on a database are only defaults for when you do CREATE TABLE without specifying them.
Similarly, the CHARACTER SET and COLLATION specified for a table are only defaults for for the columns.
To change the COLLATION for a given column(s), you need to use ALTER TABLE ... MODIFY COLUMN ....
To change the defaults, ALTER can be used on the database or table; but that only affects future tables or columns.
Another issue... The CHARACTER SET and COLLATION for any stored routine is defined when the routine is declared. To change either or both of those, you must DROP and reCREATE the routine.
Going forward, utf8mb4 is the main CHARACTER SET to use. ucs2 (and most of the other charsets) should almost never be used. If you can discover where "ucs2" originated, root it out.

MariaDB stored proc - Getting an error 'Missing SELECT' on INSERT statement

While I created loads of procs in SQL server, I want to start using MariaDB and so tried creating the simple proc below in MySQL Workbench.
I keep on getting an error stating that there is a missing SELECT on the opening '(' after the table name:
DELIMITER $$
drop procedure if exists usp_AddSentEmail$$
CREATE PROCEDURE usp_AddSentEmail (in pSender varchar(36)
,in pTo varchar(1000)
,in pSubject varchar(100)
,in pBody varchar(10000)
,in pRecordDT datetime)
BEGIN
INSERT INTO Emails('To','Subject','Body','Sender','RecordDT','Sent','SentDT')
VALUES (pTo,pSubject,pBody,pSender,pRecordDT,1,pRecordDT);
END$$
DELIMITER ;
Maybe I am trying the wrong google search but that all comes up is delimiter errors.
remove the quotes from the column names in your insert query:
INSERT INTO Emails(To,Subject,Body,Sender,RecordDT,Sent,SentDT)
VALUES (pTo,pSubject,pBody,pSender,pRecordDT,1,pRecordDT);

Creating a stored procedure with utf8 strings

I have a stored procedure with some Cyrillic strings inside. I want to check a table with a char column if the column contains some specific strings, some of them in Cyrillic. The problem seems to be that I cannot create the procedure with those strings.
SET NAMES utf8;
delimiter //
drop procedure if exists testutf8
//
create procedure testutf8()
begin
select 'ξενοδοχια';
end
//
delimiter ;
call testutf8();
Returns
?????????
show create procedure testutf8;
returns
Procedure testutf8
sql_mode STRICT_TRANS_TABLES
Create Procedure "CREATE DEFINER=xxx#% PROCEDURE testutf8() begin select '?????????'; end"
character_set_client utf8
collation_connection utf8_general_ci
Database Collation latin1_swedish_ci
So despite me using SET NAMES UTF8; the server turns my code into latin1 it seems. How can I fix this?
In store procedure input variable added
CHARSET utf8
So it look like this:
CREATE DEFINER=`root`#`%` PROCEDURE `post_content`(IN postName varchar(255), IN contentEn longtext, IN contentAR longtext CHARSET utf8, IN contentKU longtext CHARSET utf8)
...
adding ?characterEncoding=utf8 to the server url did the trick.
Try using
delimiter //
drop procedure if exists testutf8
//
create procedure testutf8()
begin
select CAST('ξενοδοχια' AS CHAR CHARACTER SET utf8);
end
//
delimiter ;