Alias Column Names at the Database Level [MySQL] - mysql

"Alias" is probably the wrong word, since that's used in the context of referencing column/table names as something else in a Query.
What I'm interested in is if there's a way to give a column two names in the database. If I were to print such a table, it would look like this:
mysql> SELECT * FROM User;
+--------------------------+-----------------+
| id | username | uname | password | pswd |
+----+---------------------+-----------------+
| 0 | bob_jones#gmail.com | some_pw_hash |
| 1 | sue_smith#gmail.com | some_pw_hash |
+--------------------------------------------+
In this case, username and uname would be synonymous in query statements, as would password and pswd.
So the following statements would have the same output:
mysql> SELECT id, username FROM User;
...
mysql> SELECT id, uname FROM User;
...
I would like to avoid having to do something like
mysql> SELECT id, username AS uname FROM User;
So, does a feature like this exist?
Cheers,
Neil

No, this is not possible. To do so, you'd have to add a new, actual second column and use triggers to keep them in sync, which would be silly.
Just write your SQL properly to use the proper column names.

If you don't mind selecting from V_User instead of User, then views can get you what you need.
CREATE VIEW V_User AS
SELECT username as username,
username as uname
FROM User;
Then these 2 queries have the same result:
mysql> SELECT id, username FROM V_User;
...
mysql> SELECT id, uname FROM V_User;
...
As Ken points out, this is not precisely what was asked. But depending on the precise context, it might be just what's needed.

Related

MySQL select statement with tablename derived from database query

I want to write a SELECT statement, where the tablename is based on the response to a different SELECT query. I can't use stacked queries, and I can only use MySQL.
As pseudo-code, this is what I'd like to do:
tablenamevariable = (SELECT 'tablename');
SELECT * FROM tablenamevariable;
Which should be equivalent to executing SELECT * FROM tablename (where the string tablename comes from the database).
What I have so far is the following, which executes successfully:
SELECT * FROM (SELECT 'tablename') AS x;
However, the result simply prints tablename (which isn't what I want).
The background is an SQL injection which upper-cases all input. So what I want to do is SELECT * FROM (SELECT CHAR([...] USING UTF8MB4)) to be able to select data from a table with lower-case characters in the name.
You can't use a string as an identifier in the same query.
A subquery or an expression can return a string, but not an identifier.
So your subquery like select ... from (select ...) as x doesn't work the way you think. It will not query from the table named by the string. It will query from a derived table which consists of the string value returned by the subquery.
mysql> select * from (select 'abc' as tablename) as x;
+-----------+
| tablename |
+-----------+
| abc |
+-----------+
The reason for this is that in SQL, all identifiers must be fixed at the time the query is parsed, before it evaluates any expressions. This is so the table names can be validated that the corresponding tables exist, and you have SQL privileges to read those tables.
Another reason is that if the subquery worked the way you expect, then there would be no way to simply query strings from a subquery without querying an hypothetical table named by those strings. Also what would you expect it to do if the subquery returned multiple columns or multiple rows?
You clarified in an edit that what you're trying to do is to query a table after your query is formatted with uppercase table names, regardless of how the table was defined.
Case-sensitivity of identifiers in MySQL is a bit complex, because MySQL has versions on different operating systems, some of which have case-sensitive filesystems and some have case-insensitive filesystems.
But the result is that in most cases, it doesn't matter that your table names are uppercase in your query. Table name comparisons are case-insensitive by default on an OS that has uses case-insensitive filesystems.
mysql> select * from mytable limit 1;
+----+-------+
| pk | name |
+----+-------+
| 3 | hello |
+----+-------+
mysql> select * from MYTABLE limit 1;
+----+-------+
| pk | name |
+----+-------+
| 3 | hello |
+----+-------+
mysql> select * from MyTable limit 1;
+----+-------+
| pk | name |
+----+-------+
| 3 | hello |
+----+-------+
(Test performed on MySQL 8.0.31 on MacOS)
On UNIX and Linux, the default is that table comparisons are case-sensitive. But there is an option to configure this if you want it to work in a case-insensitive manner on UNIX or Linux. You should read https://dev.mysql.com/doc/refman/8.0/en/identifier-case-sensitivity.html to understand how this works on different operating systems, and the option you can use to control it.
To do that you would need to use prepared statements:
set #t = 'tablename';
PREPARE stmt FROM concat('select * from ', #n);
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
It is highly unusual that you would need to do that though.

SQL select query on hashed password error

I have a simple SQL query in MYSQL.
The data type of the password column is varchar(250)
Here is my query which is meant to select the row regarding the user using their hashed password in the database:
SELECT * FROM employeeDetails
WHERE password = 'b''\xb4\xb7\xfbbA\x16\xa0\x97\xd5\x05\xd8\xb7\xfc\xeb\x06+
\x0f\x9b3)\xa3\x8d\xf6\x81\xc8\xccJ\xd6\x99\xbf\xf0\xc8'''
When I copy the password cell from the table here is the password I am trying to query in the query above:
'b'\xb4\xb7\xfbbA\x16\xa0\x97\xd5\x05\xd8\xb7\xfc\xeb\x06+
\x0f\x9b3)\xa3\x8d\xf6\x81\xc8\xccJ\xd6\x99\xbf\xf0\xc8'''
The problem is, It doesn't return any rows!
I don't know why looking for a hashed password. I would think you query the WHO is attempting login, then once that record is returned (if one so exists), THEN you have the hashed column returned and you can compare locally. What happens if for whatever strange reason you get a duplicate coincidental hash (depending on how you build your underlying stored hash). Do you let person "A" login as person "X"? Now you wont have to worry about the query of the hashed password value. If you never get the person, who cares, the hash is irrelevant.
In your request you must precede the quotes and the antislashes characters by an escape character (\)
select row with the request :
SELECT * FROM employeeDetails WHERE PASSWORD =
"\'b\'\\\xb4\\\xb7\\\xfbbA\\\x16\\\xa0\\\x97\\\xd5\\\x05\\\xd8\\\xb7\\\xfc\\\xeb\\\x06
+
\\\x0f\\\x9b3)\\\xa3\\\x8d\\\xf6\\\x81\\\xc8\\\xccJ\\\xd6\\\x99\\\xbf\\\xf0\\\xc8\'\'\'"
Is your hash string correct? It looks as though it may have been mangled by a converter of some type. Look: \xfbbA, capital A? That shouldn't be there. This b''\xb4, the b'' seems quite out of place, etc..
Look at this command:
SELECT UNHEX('4d7953514c');
The result is:
+---------------------+
| UNHEX('4d7953514c') |
+---------------------+
| MySQL |
+---------------------+
"MySQL" is just an arbitrary string I chose, it could have been any text value. But it certainly will error out on some of your chars.
mysql> SELECT UNHEX("'b''");
+-----------------------+
| SELECT UNHEX("'b''"); |
+-----------------------+
| NULL |
+-----------------------+
If you wanted to actually compare the values, you'll notice your DB-field probably looks like: Ll▒▒$o4|l▒▒Ődn▒▒, when doing a straight SELECT passwordfield FROM YourTable.
But you can get a decipherable value with....
mysql> SELECT HEX(passwordfield) FROM YourTable;
And this returns something like...
mysql> select HEX(Password) from User;
+------------------------------------------------------------------+
| HEX(Password) |
+------------------------------------------------------------------+
| 294C6CADBE246F3
+------------------------------------------------------------------+
Now that you can look at the raw, hexadecimal in the database and in the hashed password, you should be able to definitely tell if they match, and if not, what's different between the two and track it down.
You may need to fix the hashing, fix password cleansing, fix MySQL field-escaping, or use HEX() or UNHEX() in your insert/select queries, it's really hard to tell without knowing any more. The above should hopefully provide sufficient knowledge to debug further.

SQL "SELECT" Command Not Working, even though entry is in DB

I have created the following database:
CREATE TABLE QuizRepo (
User_ID BIGINT AUTO_INCREMENT PRIMARY KEY,
Name TEXT
)
I populate it via JDBC, and when I populate it, I get:
mysql> select * from QuizRepo;
| User_ID | Name |
| 1 | "XXQuiz"|
When I do the following command, it works as expected:
mysql> select * from QuizRepo where USER_ID=1;
User_ID | Name |
| 1 | "XXQuiz"|
However, when I do the following command, I get a weird result
mysql> select * from QuizRepo where Name="XXQuiz";
Empty set (0.01 sec)
Has anyone seen this happen before? How could this be possible? Perhaps I am adding it in the DB incorrectly (doesnt seem likely) but then you can clearly see there is an entry called "XXQuiz" so why is it not finding it?
It looks like you've stored the quotes as well. So you'll need to so a :
select * from QuizRepo where Name = "\"XXQuiz\"";
or similar.
Could be you name don't match exactly check for this and try also
select * from QuizRepo where Name like "%XXQuiz%";

how to select all tables with certain postfix in mysql?

I'm going to select all tables from a database that their names ends with "_language".
For example : "product_language" or "category_language" .
Can you help me?
You can select all tables using information schema using bellow given query
SELECT
TABLE_NAME
from
information_schema.TABLES
where
TABLE_SCHEMA = 'Your_schema_name'
and TABLE_NAME LIKE '%_language';
Reference for MySQL SHOW command
You can simnply go for SHOW command, like
SHOW tables like '%_language';
Then it will display all the tables in MySQL DB with the table names that are ended by the name '_language'
mysql> SHOW TABLES LIKE '%_language';
OUTPUT as
+---------------------+
| Tables |
+---------------------+
| product_language |
| category_language |
+---------------------+

Really strange error on mysql query

I have this query, and I think it talks by itself:
mysql> select id,email from members where email LIKE "%abraham.sustaita#gmail.com%";
+--------+----------------------------+
| id | email |
+--------+----------------------------+
| 272118 | abraham.sustaita#gmail.com |
+--------+----------------------------+
1 row in set (0.69 sec)
mysql> select id,email from members where email = "abraham.sustaita#gmail.com";
Empty set (0.00 sec)
mysql> select id,email from members where id = 272118;
Empty set (0.00 sec)
The data exists, but it returns empty if I use other than LIKE...
When there is such a flagrant impossible sequence of queries, then it's time to think about a table (or index) corruption and to run the Mysql CHECK command.
In that case, running REPAIR TABLE members QUICK did the trick.
If the id is a varchar and the email is a varchar they might have surrounding spaces.