Arabic text is not storing in the MySQL database - php

I wish to find out why Arabic text is not storing in the databse. It changes to some other unicode format such as %$&^%$%^&!#***.
I'v made my column Collation as utf8_general_ci. Do I need to do some modification in my sql query?
My SQL query is:
$query="INSERT INTO blog_tab(blog_details)
VALUES('$blog_details') ";

The character set, collation and encoding seem to be correct.
Adding the following before connecting to the DB is supposed to help:
mysql_query("SET NAMES 'utf8'");
mysql_query('SET CHARACTER SET utf8');
The page at http://www.adviesenzo.nl/examples/php_mysql_charset_fix/ contains an explanation and further guidance for your issue.

When you create the database, the SQL might be like this:
CREATE TABLE IF NOT EXISTS `employees` (
`empid` int(11) NOT NULL,
`empname` varchar(255) NOT NULL,
PRIMARY KEY (`empid`)
) ENGINE=InnoDB ;
or like this:
CREATE TABLE IF NOT EXISTS `employees` (
`empid` int(11) NOT NULL,
`empname` varchar(255) NOT NULL,
PRIMARY KEY (`empid`)
) ENGINE=InnoDB charset=latin1 ;
Try changing the charset to utf-8 as shown below:
CREATE TABLE IF NOT EXISTS `employees` (
`empid` int(11) NOT NULL,
`empname` varchar(255) NOT NULL,
PRIMARY KEY (`empid`)
) ENGINE=InnoDB charset=utf-8 ;
Hope this helps! :)

Related

SQL/PHP - On key update

I have messed up my database design a bit. This was the original schema:
CREATE TABLE IF NOT EXISTS `xeon_stats_clicks` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`typ` enum('1','2','3','4','5','6','7','8','9') COLLATE utf8_bin NOT NULL,
`user` varchar(20) COLLATE utf8_bin NOT NULL,
`data` varchar(10) COLLATE utf8_bin NOT NULL,
`value` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `typ` (`typ`,`user`,`data`),
KEY `data` (`data`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;
As you can see, I have KEY on the following:
UNIQUE KEY `typ` (`typ`,`user`,`data`),
KEY `data` (`data`)
I have the following code execute:
"INSERT INTO `xeon_stats_clicks` (typ, user, data, value) VALUES ('1', :username, :date, 1) ON DUPLICATE KEY UPDATE value = value + 1"
However, above code doesn't work now, as my table schema now look like this:
CREATE TABLE `xeon_stats_clicks` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`typ` enum('1','2','3','4','5','6','7','8','9') COLLATE utf8_bin NOT NULL,
`user` varchar(20) COLLATE utf8_bin NOT NULL,
`data` varchar(10) COLLATE utf8_bin NOT NULL,
`value` varchar(20) COLLATE utf8_bin NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `idx_value` (`value`),
KEY `idx_typ` (`typ`),
KEY `idx_data` (`data`),
KEY `idx_user` (`user`),
KEY `data` (`data`),
KEY `data_2` (`data`)
) ENGINE=MyISAM AUTO_INCREMENT=991799 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
How can I revert the changes made, and return to the first schema without messing up the data in the table?
I have no idea why your first schema + code doesn't work.
It works for value that is integer:
http://sqlfiddle.com/#!9/c3260/1
INSERT INTO `xeon_stats_clicks` (typ, user, data, value) VALUES
('2', 'user2', 'data3', 1) ON DUPLICATE KEY UPDATE `value` = `value` + 1
But if you will try on fiddle to apply that query to other lines it doesn't work. Because mysql can't convert VARCHAR to INT.
My guess you have wrong data in value column. For the combination of (typ, user, data, value) that you test.
UPDATE Here is the fiddle with your second schema in use:
http://sqlfiddle.com/#!9/5ea62b/1
As you can see your query works fine as well if you add
UNIQUE KEY `typ` (`typ`,`user`,`data`),
to that second schema.
and here is ALTER TABLE variant that works as well:
http://sqlfiddle.com/#!9/57b409/1
UPDATE 2 Another guess: You have broken uniqueness in your table now.
If I got you correctly you had
UNIQUE KEY `typ` (`typ`,`user`,`data`),
when start the project. After a while you did remove that UNIQUE KEY from schema. That change allowed mysql to insert duplicate records into that table. And apparently you inserted several (or a lot) of duplicates. And now you want to apply ALTER TABLE to get back unique key but mysql refuse that because of that.
Like here: http://sqlfiddle.com/#!9/4cbb5 <-- uncomment ALTER line to see error message
So you need to fix uniqueness first.
UPDATE 3 Delete duplicates:
http://sqlfiddle.com/#!9/85f228/1
DELETE FROM xeon_stats_clicks USING xeon_stats_clicks
INNER JOIN xeon_stats_clicks dup
ON xeon_stats_clicks.id < dup.id
AND xeon_stats_clicks.typ = dup.typ
AND xeon_stats_clicks.user = dup.user
AND xeon_stats_clicks.data = dup.data;

Why won't this binded MySQL query run?

My code for updating user info:
if($update_stmt = $link_reg->prepare("UPDATE email_pass SET password=?, salt=?, customer_id=?, subscription_id=?, subscription_datetime=? WHERE email=?")){
$update_stmt->bind_param('ssssss', $new_password, $random_salt, $new_customer_id, $new_sub_id, $new_sub_datetime, $new_email);
if($update_stmt->errno){
echo($update_stmt->error);
}
// Execute prepared query
if($update_stmt->execute()){
// MORE CODE HERE
} else {
echo("ERROR?");
}
}
When I run it, I get no feedback. My data table doesn't update, but there's no echo message either.
Is there an error somewhere? Why won't the code execute properly?
EDIT
Here's some sample UPDATE data and the table's columns
$new_password = '532a69d8124604e33e9f45a8c9xbea92c342cbd5a3f847f770816dbd97975b2769f52a25806ead6100c1ac1a9a1a4de6b1641279a26854fba7c162caffca8e9f';
$random_salt = 'b6a1062d2c07c3aa900cbe9777d4670192f77241ad0b5ceb5f7968e3107f6d719b450d2ac37165e7827f53c2005797c985deddb9bec71724948bcd833ea72e87';
$new_customer_id = '19582601';
$new_sub_id = 'crj94x';
$new_sub_datetime = '2014-02-25 19:41:56';
$new_email = 'myemail#someemailplace.com';
The CREATE TABLE syntax:
CREATE TABLE `email_pass` (
`row_id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`password` char(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`salt` char(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`customer_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`subscription_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`subscription_datetime` datetime NOT NULL,
PRIMARY KEY (`row_id`)
) ENGINE=MyISAM AUTO_INCREMENT=239 DEFAULT CHARSET=latin1
I have tried your code and it works. You have a WHERE email=? in your code, which is populated with $new_email. May it be that you are trying to find the record to update by searching for the new email to be set rather than by the current email address (or where row_id = ...)?
I.e. you do not get any errors and nothing is updated because you do not get a match on your email = <new email> where clause.
Welp, turns out I forgot to give the MySQL user permission to UPDATE. It could only SELECT and INSERT.

mysqli delete query not working

I'm writing a PHP script to delete a row from a MySQL database by id.
The value of the id is passed as a query string and stored in a variable.
The query runs normally, with no errors, but no rows are affected.
Here is my code, can somebody please point out what's wrong with it?
Thanks.
PHP Code:
$delete = $_GET['killthisguy'];
$sqlDel = "DELETE FROM `pba_files` WHERE id=".$delete;
$res = mysqli_query($cxn, $sqlDel);
$affRows = mysqli_affected_rows($cxn);
Database Schema:
CREATE TABLE IF NOT EXISTS `pba_files` (
`id` int(3) NOT NULL auto_increment,
`chap_id` int(2) default NULL,
`cat_id` varchar(2) character set utf8 collate utf8_unicode_ci default NULL,
`is_video` tinyint(1) default NULL,
`file_location` varchar(220) character set utf8 collate utf8_unicode_ci default NULL,
`clean_filename` varchar(116) character set utf8 collate utf8_unicode_ci default NULL,
`description` varchar(1026) character set utf8 collate utf8_unicode_ci default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=611 ;
You could try removing the ' from the "id" because it is not a string, it is an int (from the database point of view)
$delete = $_GET['killthisguy'];
$sqlDel = "DELETE FROM `pba_files` WHERE id=".$delete;
$res = mysqli_query($cxn, $sqlDel);
$affRows = mysqli_affected_rows($cxn);
Also are you sure that the "id" exists in the table?
The issue was just a careless mistake I made when setting up my access rights. DELETE was not allowed for my user on the database.
Thanks for all your help guys.

PHP PDO - MySQL Query Create or Update (unique index)

hope you are well.
I have a table in a MySQL (MariaDB) database with the below schema:
CREATE TABLE `scheduled_immobilise` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`account` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
`device` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
`allow_from` time DEFAULT NULL,
`allow_to` time DEFAULT NULL,
`active` varchar(6) COLLATE utf8_unicode_ci DEFAULT NULL,
`last_updated` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`cron_id_from` int(11) DEFAULT NULL,
`cron_id_to` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique` (`account`,`device`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
What I am trying to do is write a query that will either create a row (if the unique index doesn't exist), or if it already exists update it. I know you can do this by doing a select query first, but ultimately i was hoping to avoid this. Below is the SQL query I am using to create. Please note this is using PDO named placeholders..
INSERT INTO
scheduled_immobilise (
account,
device,
allow_from,
allow_to,
active
)
VALUES (
:account,
:device,
:allow_from,
:allow_to,
:active
)
Any help is much appreciated, thanks in advance!
Paul.
There's exactly a mysql option for this
INSERT INTO
scheduled_immobilise (
account,
device,
allow_from,
allow_to,
active
)
VALUES (
:account,
:device,
:allow_from,
:allow_to,
:active
)
ON DUPLICATE KEY UPDATE account = :account, device = device...etc
a slightly more correct answer
INSERT INTO
scheduled_immobilise (
account,
device,
allow_from,
allow_to,
active
)
VALUES (
:account,
:device,
:allow_from,
:allow_to,
:active
)
ON DUPLICATE KEY UPDATE
account = values(account),
device = values(device)
...etc
it will let you to use placeholders of any type, in any mode and with any driver beside PDO, while other answer will work only if emulation mode for PDO is turned on.

full-text search 2 tables

I have two tables. One stores video information, the other stores the tags associated with that video. They share the common field vid_id. I am trying to fulltext search both tables for matches. The goal is that if there is a match in either table, then all fields with that vid_id be gathered from video.
The problem is my query just crashes with Call to undefined method PDOConnectionFactory::errorInfo(). It should return one row since there is one entry in tags where name field = test. Anyone have any ideas? I have been struggling with this for a while.
CREATE TABLE IF NOT EXISTS `tags` (
`id` varchar(35) NOT NULL,
`vid_id` varchar(35) NOT NULL,
`name` varchar(45) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
UNIQUE KEY `vid_id` (`vid_id`,`name`),
FULLTEXT KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `video` (
`timestamp` int(11) NOT NULL,
`vid_id` varchar(32) NOT NULL,
`file_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`uploader` varchar(55) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`title` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`subject_id` int(1) NOT NULL,
FULLTEXT KEY `title` (`title`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
$sql = "SELECT video.*
MATCH(video.title) AGAINST('?') as cscore,
MATCH(tags.name) AGAINST('?') as htscore
FROM video
LEFT JOIN tags ON video.vid_id=tags.vid_id
WHERE
MATCH(video.title) AGAINST('?') OR
MATCH(tags.name) AGAINST('?')
ORDER BY cscore DESC;";
$stmt4 = $conn->prepare($sql);
$result=$stmt4->execute(array('test','test','test','test')) or die(print_r($db->errorInfo(), true));
The problem is that you're missing a comma (,) after SELECT video.* in your SQL query.
Working example:
SELECT video.*,
MATCH(video.title) AGAINST('?') as cscore,
MATCH(tags.name) AGAINST('?') as htscore
FROM video
LEFT JOIN tags ON video.vid_id=tags.vid_id
WHERE
MATCH(video.title) AGAINST('?') OR
MATCH(tags.name) AGAINST('?')
ORDER BY cscore DESC;

Categories