SQL query fails with DB fields strings containing apostrophe - mysql

I'm querying a MySQL DB with some strings in one field which contain apostrophes which I cannot remove or escape when adding to the DB. How do I format a query not to fail on a string containing an apostrophe? For example, doing a query against a FULLTEXT indexed field:
"SELECT * FROM NationalTideStationsA WHERE MATCH(location) AGAINST('$myState')";
This fails whenever the returned string has an apostrophe, for example, when the location field contains:
"Cedar Tree Neck, Martha's Vineyard, Massachusetts"
all queries for locations in Massachusetts fail.
I cannot work out if SQL offers a way to format the query to cope with that.
The SELECT query works just as desired otherwise.

Agreed on the suggestion to read up on sql injection. For the immediate, replace all single quotes with two single quotes.

Related

Can I parameterize a create statement in Go?

Using the Go SQL library we can create SELECT, INSERT, UPDATE and DELETE statements with parameters like this:
db.Query("SELECT * FROM database.table WHERE param = ?", param_value)
I want to create tables from user provided input that describes the table structure, users will be asked for the name of the table and the name and type of each column they want to create. However, building a CREATE statement in the query interface Creating a CREATE statement by concatenating strings together works, but that's a SQL injection attack waiting to happen.
Is there a way to parameterize CREATE statements using the Go SQL library?
SQL query parameters take the place of a scalar value only.
That is, you can use a parameter to substitute only where you would otherwise use a constant quoted string, constant quoted date/time, or constant numeric.
SQL query parameters can't be used for:
Table names, column names, or other identifiers
SQL expressions
Lists of scalar values (like in an IN(...) predicate)
SQL keywords
The proper way to write your app that takes user input which describes table structure is to interpret the user input as a guide, not as literal SQL syntax. Avoid passing user input (or any unsafe content) through to be executed as part of any SQL statement.

How do I handle unescaped MySQL data in a SELECT query?

Background:
User submits the following data firstName
I escape user's data using mysql_real_escape_string and store it in MySQL memory table (table1).
A PHP cron runs every 5 minutes then SELECTS this data into a PHP array (for replication reasons) and executes the following INSERT command to an identical table but in InnoDB format (table2):
INSERT INTO `table2` (`id`,`firstName`) VALUES ('1','aaa');
Problem:
If a user sends data with a single quote ', i.e, "John's", it is escaped WHILE saving, but not saved escaped. Meaning, it's saved with the single quote into firstName of table1.
When the above insert command takes place, the unescaped data breaks the whole insert command. How do I deal with this without manually escaping at every juncture?
I can't shift to PDO or mysqli at the moment.
You cannot avoid this without manually escaping data everytime you use it in a literal SQL query. Either use parametrized statements or escape your data.
What do you mean with your "replication reasons"? Maybe you don't need to fetch all data from your database, just so you can push it back into another table. Inserting directly from another table is much more efficient.

MySQL Uncompress issue

I am facing issue with MySQL, UNCOMPRESS function.
I have table named as user and user_details stores COMPRESS values. In this case before search for values from the user_details i have to UNCOMPRESS it.
But issue is after I do UNCOMPRESS, search become case-sensetive.
Like.. e.g
If I tries below sql, it will only search for values which contain CAPITAL TESTING word and ignore small case testing word
SELECT * FORM user WHERE UNCOMPRESS(user_details) LIKE '%TESTING%'.
I want case-insensitive search.
But issue is after I do UNCOMPRESS, search become case-sensetive.
This is because COMPRESS() "Compresses a string and returns the result as a binary string." (emphasis mine)
When you perform a LIKE operation on a binary string, a binary comparison will be performed (which is case-sensitive).
You may be able to circumvent this by putting a CAST() around the COMPRESS() statement.
But you probably shouldn't be doing this in the first place. It's an extremely inefficient way to search through huge amounts of data. MySQL will have to uncompress every row for this operation, and has no chance of using any of its internal optimization methods like indexes.
Don't use COMPRESS() in the first place.
Try this:
SELECT * FROM `user` WHERE LOWER(UNCOMPRESS(user_details)) LIKE '%testing%'
But as Pekka well pointed or its very inefficient . If your using MyIsam Engine another alternative is myisampack which compresses the hole table and its still query-able.

I don't understand this piece of MySQL notation and subsequently don't know how to do it in Postgresql

I have this MySQL query, and it works on a MySQL database, but not on a PostgreSQL one:
select setype from _entity where id='72#78|'
Now, what exactly is '72#78|' trying to do? id is an integer field, so when the query is run on a Postgressql DB, it gives an invalid input syntax for integer: "72#78|" error.
I know that | is a bitwise OR operator, but what exactly is being ORED here? And, just as importantly, what is the # for? I tried to look for it in the MySQL manual, but due to sub-par searching skills, I couldn't find it.
When I run the above query on a MySQL DB, it finds data with an id value of 72,somehow, the expression evaluates to the first number.
So, what is the above query trying to do, and how do I convert it into a PostgreSQL equivalent?
Thanks for all your help, have a good day.
MySQL is converting the text string to a numeric, and ignoring anything after the first non-numeric character, therefore, it is just comparing id = 72, which is what you are getting from the output.
My guess is that PostgreSQL is trying to convert the whole string to an integer and failing because it isn't a valid integer value.
To do the equivalent in PostgreSQL, you would need to convert the 72#78| to a simple integer before running your query.

Use SQL functions for insert/update in ActiveRecord

I want to store IP addresses (v4 and v6) in my rails application. I have installed an extension to MySQL adds functions to convert ip strings to binary which will allow me to query by IP range easily.
I can use unescaped sql statements for SELECT type queries, thats easy.
The hard part is that I also need a way to overwrite the way the field is escaped for insert/update statements.
This ActiveRecord statement
new_ip = Ip.new
new_ip.start = '1.2.3.4'
new_ip.save
Should generate the following SQL statement
INSERT INTO ips(start) VALUES(inet6_pton('1.2.3.4'));
Is there a way to do this? I tried many things, including overriding ActiveRecord::Base#arel_attributes_values, without luck : the generated sql is always converted to binary (if that matters, my column is a MySQL VARBINARY(16)).
ActiveRecord::Base.connection.execute("INSERT INTO ips(start) VALUES(inet6_pton('1.2.3.4'))")