MySQL grant select to all columns in table except one column - mysql

It is possible to grant select all columns in table except one for user?
I tried to search any way to do this and read some docs, but can`t find solution

For example, you want to grant update privilege on ename column only, then give the following statement (where xyz is the username)
grant update (ename) on emp to xyz;

You have to name all the other columns, which could be tedious if it is a large table.
GRANT SELECT(col1,...,col99)
ON table_name
TO user_name

Related

List of all table and column level privileges for a MySQL database

What is the easiest way to list all table-level and column-level privileges for a MySQL database? I need to know what level of customized access has been granted for a specific database and which users have fine-tuned access to certain tables and/or columns.
To list table level privileges, you can query the INFORMATION_SCHEMA.TABLE_PRIVILEGES table.
The TABLE_PRIVILEGES table has these columns:
GRANTEE : the name of the account to which the privilege is granted, in 'user_name'#'host_name' format.
[...]
TABLE_NAME : the name of the table.
PRIVILEGE_TYPE : The privilege granted. The value can be any privilege that can be granted at the table level; [...] . Each row lists a single privilege, so there is one row per table privilege held by the grantee.
To list column level privileges, have a look at the INFORMATION_SCHEMA.COLUMN_PRIVILEGES table.
All table/column level privileges for a specific database:
SELECT * FROM `INFORMATION_SCHEMA`.`TABLE_PRIVILEGES` WHERE TABLE_SCHEMA = 'my_database';
SELECT * FROM `INFORMATION_SCHEMA`.`COLUMN_PRIVILEGES` WHERE TABLE_SCHEMA = 'my_database';
Using pt-show-grants from percona toolkit.

MySQL: DELETE permission requires SELECT permission?

The user has INSERT and DELETE permissions but not SELECT permission. The user can write records but not read. When trying to "DELETE from my_table WHERE id=5" you get "#1143 select not allowed...". Is there a way to solve this?
Privileges
You need the DELETE privilege on a table to delete rows
from it. You need only the SELECT privilege for any columns that are
only read, such as those named in the WHERE clause.
source
Conclusion : If you use a where in the Delete you need the Select privilege too.

Overriding an implied database in a MySQL UNION?

I swear, this is for educational purposes only...
The MySQL query looks like this:
SELECT *
FROM mytable
where name='value' AND addr='value'
UNION SELECT *
FROM mysql.user;
But the error I get is that there is no mysql.mytable table.
Is there anything I can do in my union or in either of those values to make my query valid? Other than explicitly stating the mytable database name in the code? Let's assume I can't change anything in the query before the 'value'.
It's not very clear what are you trying to select from information_schema.user. information_schema is the standard MySQL database, it's there by default. However there is no user table in this database.
To view a list of your databases, do this in your MySQL console:
show databases;
To view tables in a database:
use information_schema
show tables;
From what you are saying, it looks like you are using information_schema database by default. Also you are trying to select mytable in this database, this table doesn't seem to exist either. Can you run the commands above and show us the output?
Update: If you need to select from two different databases:
select * from mydatabase.mytable union select * from mysql.users
Either remove mydatabase if mytable is in your current database or provide a proper name of your database instead. mydatabase here is just an example.
However, as already been pointed out to you, you should either have identical columns in both tables, or specify identical columns to be selected from each table.
For functional and valid UNION clause, you must have the same columns in both queries. Missing columns in a select, highlight default NULL with aliases:
Select *, NULL as "column1" FROM table1 ...

Cannot access table in 2nd database from MySQL query

I have 2 databases on a server:
database1
database2
I am trying to query a table in each database. However, when I try that, I get the following error:
Unknown table 'database2.client' in field list
Here is the code that I am using in a script running on database 1:
SELECT database2.client.id;
It returns the unknown table error. The odd thing is that if I query for the databases, it shows them both:
SHOW DATABASES
it returns the following:
information_schema
database1
database2
I'm not sure why the SHOW syntax confirms that both databases are there, but I'm not able to select data from the other table.
Try this:
SELECT id FROM database2.client;
I believe the correct syntax would be:
SELECT id FROM database2.client
Where id is the column, database2 is your database, and client is your table.
Can you select it if you first run use database2, and then SELECT client.id?
EDIT:
As many people have pointed out, you need to use the correct SELECT syntax.
USE database2;
SELECT id FROM client;

Grant a user permission to only view a MySQL view and nothing else

This question was originally using MySQL 5.1.44, but is applicable to MySQL 8.0+ too.
Let's say I have a table with records inserted by different users of my application. How can I give a specific user access to only see his/her records in that table? I've thought about creating a VIEW with his/her records, but I don't know how to create a MySQL user that can only see that VIEW.
So, is it possible to create a MySQL user that only has access to a single VIEW? Can this user also be made so they read-only access to that VIEW?
Thanks!
PS: What I call users in my example are really subsidiary offices that want to access their records with their own applications.
GRANT SELECT ON database1.view1 TO 'someuser'#'somehost';
Besides
GRANT SELECT ON <database_name>.<view_name>
TO <user>#<host>
it's better to also do
GRANT SHOW VIEW
ON <database_name>.<view_name> TO <user>#<host>
so that a lot of SQL UI tool can get the view definition and work appropriately for the view.
I believe the original question is actually asking how to limit the rows to those owned by a given user. (The idea of creating one view per user, and then granting just that, seems like a workaround.)
You can do this by inserting the user() reference into the data table, and then filtering on that.
Using MySQL 5.6. Create a view that limits SELECT to just records owned by the current user:
-- check the current user
select user();
create table t1 (myId int, mydata varchar(200), myName varchar(200));
insert t1 select 1, 'my data yes', user();
insert t1 select 2, 'my data yes2', user();
insert t1 select 3, 'my data no', 'joe';
select * from t1;
create or replace view v1 AS
select * from t1 where myName = user();
select * from v1;
GRANT SELECT ON <database name>.<view name>
TO <user>#<host> IDENTIFIED BY '<password>'
Source: MySQL Documentation
If you want to make the view read only which I suspect you do. Then you should create the view with the ALGORITHM = TEMPTABLE clause.
This will make the view read only virtue of it having to create a temp table.
Another way to achieve read only and this is depends on your data is to stick an aggregate function. For example if you have a view which is based on a table and shows all columns then you can stick a distinct onto the select.