UTF-8 Bad Encoding when Using ZF2 dbAdapter for mySQL for Update - mysql

I am getting the Exception when I attempt to update the record with "tableGateway" object:
Zend\Db\Adapter\Exception\InvalidQueryException
Statement could not be executed
(HY000 - 1300 - Invalid utf8 character string: 'C`\xC3`\xB3`digo')
I have the following table structure with data in mySQL:
CREATE TABLE `clientes` (
`Código` int,
`Nome` varchar(50),
`Descricao` varchar(150)
....
);
INSERT INTO `clientes` (`Código`, `Nome`, `Descricao`)
VALUES (1, 'Test Nome', 'Test Descricao');
The database encoding is 'latin1', but the database configuration is as shown:
'mycnn' => array(
'driver' => 'pdo',
'dsn' => 'mysql:dbname={$mydb};host={$myhost}',
'username' => '{$myuser}',
'password' => '{$mypassword}',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
)
As you can see the above scenario, I have setup the driver for "UTF-8", the column name "Código" has a special character and renaming this column is not an option.
The syntax that I am using for updating in the model is:
$set = array("Nome" => "Edited Test");
$where = array("Código" => 1);
$this->tableGateway->update($set, $where);
After that, the ZF is parsing the SQL throwing the Exception:
UPDATE "clientes" SET "Nome" = 'Edited Test' WHERE "C`\xC3`\xB3`digo" = 1
I have also removed the UTF-8 option, since the catalog is "latin1_swedish_ci" without success.
I would appreciate anyone who gives me a hint how to face this issue.
Thanks in advance.

Make sure your database encoding type is UTF-8.
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
Make sure fields have utf8_general_ci.
In your layout phtml head has
<meta charset='utf-8'>
Updated
As you said you are not able to change encoding to utf-8 so use one of the following commands using driver_options
'SET NAMES \'latin1\'' or 'SET CHARACTER SET \'latin1\''
For more details check out the doc please!
When problem with column name which has latin1 characters
Just pass the condition as string not an array as the second argument into TableGateway's update() method. But you must set this 'SET NAMES \'UTF8\'' in your driver_options.
$id = 1;
$where = "Código = {$id}";
// Or use this way
$where = "Código = 1";
$this->tableGateway->update($set, $where);

Related

Replace variables extracted from database with theirs values

I'd like to translate a perl web site in several languages. I search for and tried many ideas, but I think the best one is to save all translations inside the mySQL database. But I get a problem...
When a sentence extracted from the database contains a variable (scalar), it prints on the web page as a scalar:
You have $number new messages.
Is there a proper way to reassign $number its actual value ?
Thank you for your help !
You can use printf format strings in your database and pass in values to that.
printf allows you to specify the position of the argument so only have know what position with the list of parameters "$number" is.
For example
#!/usr/bin/perl
use strict;
my $Details = {
'Name' => 'Mr Satch',
'Age' => '31',
'LocationEn' => 'England',
'LocationFr' => 'Angleterre',
'NewMessages' => 20,
'OldMessages' => 120,
};
my $English = q(
Hello %1$s, I see you are %2$s years old and from %3$s
How are you today?
You have %5$i new messages and %6$i old messages
Have a nice day
);
my $French = q{
Bonjour %1$s, je vous vois d'%4$s et âgés de %2$s ans.
Comment allez-vous aujourd'hui?
Vous avez %5$i nouveaux messages et %6$i anciens messages.
Bonne journée.
};
printf($English, #$Details{qw/Name Age LocationEn LocationFr NewMessages OldMessages/});
printf($French, #$Details{qw/Name Age LocationEn LocationFr NewMessages OldMessages/});
This would be a nightmare to maintain so an alternative might be to include an argument list in the database:
#!/usr/bin/perl
use strict;
sub fetch_row {
return {
'Format' => 'You have %i new messages and %i old messages' . "\n",
'Arguments' => 'NewMessages OldMessages',
}
}
sub PrintMessage {
my ($info,$row) = #_;
printf($row->{'Format'},#$info{split(/ +/,$row->{'Arguments'})});
}
my $Details = {
'Name' => 'Mr Satch',
'Age' => '31',
'LocationEn' => 'England',
'LocationFr' => 'Angleterre',
'NewMessages' => 20,
'OldMessages' => 120,
};
my $row = fetch_row();
PrintMessage($Details,$row)

Ruby Mysql2 Client not taking backslash while insert

We are using production and staging databases in our application.
Our requirement is to insert all the records to staging database when ever a record is added in production database, so that both the servers are consistent and same data.
I have used Mysql2 client pool to connect to staging server and insert the record that is added to production.
here is my code:
def create
#aperson = Person.new
#person = #aperson.save
if #person && Rails.env == "production"
#add_new_person_to_staging
client = Mysql2::Client.new(:host => dbconfig[:host], :username => dbconfig[:username], :password => dbconfig[:password], :database => dbconfig[:database])
#person_result = client.query('INSERT INTO user_types(user_name, regex, code) Values ("myname" , "\.myregex\." , "ns" );')
end
end
Here "#person_result" record is inserted to mysql table but the "regex" column eliminates "\" slashes.
like : user_name = myname, regex = .myregex., code = ns
when I manually execute the "Insert" query in mysql command line it inserts as it is along with \ slash. but not through "client.query"
Why does \ slash is eliminated. please help me here.
Thanks.
\ is likely being removed by the MySQL2 client as part of a SQL injection protection preprocessor.
Have you looked at trying either a double backslash or using the escape method to properly escape the string?
Try using this
#person_result = client.query('INSERT INTO user_types(user_name, regex, code) Values (myname , "\."+myregx+".\" , ns )')

Storing a String saved as a Variable in a MySQL database?

In a ruby script that sends information to the TWILIO API, I have a string of characters of characters that their (Twilio's) API outputs. I then have the console output it so I can save it as a variable and reuse it later:
#client = Twilio::REST:Client.new account_sid, auth_token
call = #client.account.calls.create({:from => 'incoming', :to => 'outgoing', :url => 'url', :method => 'GET'})
puts call.sid
This part is functional, but now when I rename the variable (// #incoming_Cid=call.sid //) as to input it into a MySQL database, I bump into an issue. (The 34 character ID has numbers and letters, so I define the datatype as VARCHAR).
begin
dbh = DBI.connect("DBI:Mysql:db_name:localhost",
"user", "pass")
dbh.do ("INSERT INTO calls (column_name)" #//Select the column to insert
"VALUES (incoming_Cid)") #Insert the 34 character string.
dbh.commit
puts "Customer SID has been recorded"
rescue
puts "A database occurred"
puts "Error code: #{e.err}"
puts "Error message: #{e.errstr}"
ensure
dbh.disconnect if dbh
end
Right here at the dbh.do ("INSERT INTO calls " line if I put the incoming_Cid variable in the VALUES() instead of seeing a 34-char-string, like CA9321a83241035b4c3d3e7a4f7aa6970d, I literally see 'incoming_Cid' appear in the database when I execute select * in calls.
How can I resolve this issue?
You need to use string interpolation: "VALUES (#{#incoming_Cid})"

Using PDO to insert variables into SELECT clause?

I am attempting to get the distance from a user to each venue stored in a MySQL database, using the spherical law of cosines. The user inputs their location, and the following query is executed.
$data = array(':lat' => $lat, ':lon' => $lon);
$qry = "SELECT ACOS(SIN(v.Latitude) * SIN(:lat) + COS(v.Latitude) * COS(:lat) * COS(:lon - v.Longitude)) * 3963 AS distance FROM Venue v";
$stmt = $pdo->prepare($qry);
$stmt->execute($data);
$rows = $stmt->fetchAll();
The problem is, I get the following error.
PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY093]: Invalid parameter number'
When I remove the variables (:lat and :lon) from the SELECT clause, it works just fine. Other variables further on in the statement (not shown here) work just fine, it is only the variables in the SELECT clause that cause an issue. Is this inability to use PDO variables within SELECT clauses a limitation of PDO, or is there a way around this issue?
I am using PHP 5.4.15, and my PDO options are as follows.
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', // UTF-8 to prevent issue sending special characters with JSON
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // fire exceptions for errors (turn this off for release)
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // only return results indexed by column name
PDO::ATTR_EMULATE_PREPARES => false // actually prepare statements, not pseudo-prepare ( http://stackoverflow.com/questions/10113562/pdo-mysql-use-pdoattr-emulate-prepares-or-not )
);
$data = array($lat, $lat, $lon);
$qry = "SELECT ACOS(SIN(v.Latitude) * SIN(?) + COS(v.Latitude) * COS(?) * COS(? - v.Longitude)) * 3963 AS distance FROM Venue v";
$stmt = $pdo->prepare($qry);
$stmt->execute($data);
$rows = $stmt->fetchAll();

Failed to insert value into tables in Ruby Mysql

I am trying to use Ruby to insert values into MySQL on localhost. The value i want to insert is the result from Twitter search. My program can successfully write the result to a file, so now i want to insert the result to MySQL. Here is part of my code:
results = #search.perform("yahoo", 100)
client = Mysql2::Client.new(:host => "localhost", :username => "root", :password => "123", :database => "db1")
results.map do |status|
insert = client.query ("INSERT INTO table1 (fromuser, tweet) VALUES (#{status.from_user},#{status.text})")
end
The error is "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near " tweet " at line 1 (Mysql2::Error).
What caused the error?
Another problem i have found is that when i used following code to insert value to MySQL ,i got another error: "Unknown column 'a' in 'field list' (Mysql::ServerError::BadFieldError)"
require 'mysql'
require 'rubygems'
sql = Mysql.real_connect("localhost", "root", "123", "db1")
st1 = "a"
st2 = "b"
user_string = "(#{st1},#{st2})"
query="INSERT INTO table1 (fromuser, tweet) VALUES" + user_string
sql.query(query)
I want to insert "a" and "b" into table.
How to solve this?
Thanks in advance,
Like Andrew said, you definitely want to escape your data.
I think you also need to quote the values:
insert = client.query("INSERT INTO tweets (from_user, tweet_text)
VALUES ('#{client.escape(status.from_user)}',
'#{client.escape(status.text)}')")
You need to use CREATE TABLE to create a table in your database to insert the data into. At the moment you are saying you want to insert the data into the database name ("db1") itself.
Also, you must escape your data first:
insert = client.query("INSERT INTO tweets (from_user, tweet_text)
VALUES (#{client.escape(status.from_user)},
#{client.escape(status.text)})")