I want to select the nth element of the table list provided by the SHOW TABLES query.
If I use the following code to list them alphabetically:
WITH tableslist as (SHOW TABLES)
SELECT Tables_in_DBname FROM tableslist ORDER BY Tables_in_DBname
I get an error regarding the syntax near 'SHOW TABLES).
If I only do the SHOW TABLES query I get a table with the column Tables_in_DBname.
The main goal of this would be to populate a checkbox in VBA with the table names in the database, so in case I am looking in the completely wrong direction to go about this please correct me.
I am able to populate the cbo with the fields of specific tables, but I could not find a way to list the tables from the database as fields, so I am attempting to make an ordered list to select the nth element from.
The server type is MariaDB.
You can use information_schema.tables to get the list of tables:
SELECT table_name FROM information_schema.tables
WHERE table_schema = '<name of database>' ORDER BY table_name;
This allows you to build more complex queries that inspect the tables in the database.
Related
We have an exercise and are struggling to come up with a sql injection to find more data from the database in mySQL.
Here is how far we have got:
mySQL webpage result
In the above picture you can see we have managed to get the database to divulge the userid, user and passwd values.
To achieve this we have typed:
admin' --
in the login box
Then:
' union select table_name from information_schema.tables --
in the password box
However, this is not the entire goal of the exercise. We must discover the databases and tables that are available.
We are unsure why the response is not taking into account our query union select table_name from information_schema.tables.
Here is an example of what the response is if nothing is typed in either login or password box:
default mySQL webpage
Our tasks:
enumerate available tables in the database
find username with userid of 3 (done - right?)
find a table containing md5 hashes
Could someone point us in the right direction?
Why isnt our select table_name from information_schema.tables working?
UPDATE: we managed to get 238 rows returned after restructuring our initial query in the first login box to:
admin’ union select table_name,2,3 from information_schema.tables -- -
The fix: the amount of columns have to match between first select query and union select query.
You'll probably have to put the entire injection in the username box. At the moment the -- after the admin' in the login input is commenting the rest of the query.
i.e. The login box should contain admin' UNION SELECT table_name FROM information_schema.tables --
You may need to select padding columns from information_schema.tables as there is no way to tell how many columns the users table has.
My scenario is as follows( in MySQL)
I have a table say table 1, which has 2 columns:
userID, column_acess
Table 2 which has a list of columns say col1,col2,col3, etc.
Now What I would like to do is use pymySQL to query table 1 for the columns a particular userID is allowed to acesss, by inspecting the column, acess field ( which will contain a comma seperated list of columns in tabl2), and use that result in another sql query ( which works on table2) to actually get the data from the respective columns a user is allowed to acess.
So essentially I would like something like:
Select (Select column_acess from tabl1 where user_ID='123') from table2
So inner query should return the list of columns say col1, col2, which would be used to select the columns in the outer query in table2
How do I do that in mySQL?
I strongly encourage you too read this post. You should either first store columns in variable or use dynamic sql query. Use SELECT result as COLUMN name in other SELECT
BTW your schema is not even in 1 NF since you don’t have atomic values in table 1. You should avoid that.
MySQL supports the granting of column-level privileges to users, using the standard grant statement.
I would suggest that you start with the documentation on this subject.
An alternative to using grant for columns is to create views for different user types. This is, in fact, the more general solution, because the views can filter rows as well as columns. The idea is that the underlying tables are not directly accessible. The views are, so all access needs to go through the views.
I'm trying to use INFORMATION_SCHEMA, because I think it will help a lot on what i want to do. I tried to find the right query, but none of them worked. The common thing in all queries was that I used nested queries on different databases. The last one I used was this one below.
SELECT table_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE column_name='field1'
AND table_schema='database1'
AND (SELECT * FROM database1.table_name WHERE field1 > somevalue ) IS
NOT NULL
But this returned error
#1146 - Table 'database1.table_name' doesn't exist.
Is this because i'm using two nested queries each to a different database? Is there a way I can make this work?
What I want to do is a list of the table names of a database which have field1 in their field list and at least one of the values of field1 is greater than somevalue.
I use MySQL v5.5
I'd advice you to use a join other than a nested query
I have a query like this :
SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo WHERE group='BEST'
Basically, the table name for the main query is fetched through the subquery.
I get an error that #1054 - Unknown column 'group' in 'where clause'
When I investigate (removing the where clause), I find that the query only returns the subquery result at all times.
Subquery table adm_linkedfields has structure id | name | linktable
Currently am using MySQL with PDO but the query should be compatible with major DBs (viz. Oracle, MSSQL, PgSQL and MySQL)
Update:
The subquery should return the name of the table for the main query. In this case it will return tbl_company
The table tbl_company for the main query has this structure :
id | name | group
Thanks in advance.
Dynamic SQL doesn't work like that, what you created is an inline-view, read up on that. What's more, you can't create a dynamic sql query that will work on every db. If you have a limited number of linktables you could try using left-joins or unions to select from all tables but if you don't have a good reason you don't want that.
Just select the tablename in one query and then make another one to access the right table (by creating the query string in php).
Here is an issue:
SELECT * FROM (SELECT linktable FROM adm_linkedfields WHERE name = 'company') as cbo
WHERE group='BEST';
You are selecting from DT which contains only one column "linktable", then you cant put any other column in where clause of outer block. Think in terms of blocks the outer select is refering a DT which contains only one column.
Your problem is similar when you try to do:
create table t1(x1 int);
select * from t1 where z1 = 7; //error
Your query is:
SELECT *
FROM (SELECT linktable
FROM adm_linkedfields
WHERE name = 'company'
) cbo
WHERE group='BEST'
First, if you are interested in cross-database compatibility, do not name columns or tables after SQL reserved words. group is a really, really bad name for a column.
Second, the from clause is returning a table containing a list of names (of tables, but that is irrelevant). There is no column called group, so that is the problem you are having.
What can you do to fix this? A naive solution would be to run the subquery, run it, and use the resulting table name in a dynamic statement to execute the query you want.
The fundamental problem is your data structure. Having multiple tables with the same structure is generally a sign of a bad design. You basically have two choices.
One. If you have control over the database structure, put all the data in a single table, linktable for instance. This would have the information for all companies, and a column for group (or whatever you rename it). This solution is compatible across all databases. If you have lots and lots of data in the tables (think tens of millions of rows), then you might think about partitioning the data for performance reasons.
Two. If you don't have control over the data, create a view that concatenates all the tables together. Something like:
create view vw_linktable as
select 'table1' as which, t.* from table1 t union all
select 'table2', t.* from table2 t
This is also compatible across all databases.
Is it possible to retrieve the count of the number of columns a query returns? This can be easily done with a bound scripting language such as php, but I'm looking for db only solution.
Example:
CountCols(SELECT 'a','b','c')
=> 3
CountCols(SELECT * FROM information_schema.session_variables)
=> 2
Would this work for you?
select
count(*)
from
`information_schema`.`columns`
where
`table_schema` = 'my_table_schema' and `table_name` = 'my_table_name';
You only need to use table_schema if the table name exists in more than one database.
Based on your response comment, you are looking to count a dynamic number of columns. You may be able to do this with a temporary table, but you cannot access the data of a temporary table without possibly installing a patch.
Of note, there is a similar outstanding SO question asking how to select columns from a temporary table.
Well if you want to know the columns in a table just do:
DESCRIBE `table_name`
Otherwise there is no "real" way to get the number of columns in a select query since other than selecting * you select certain columns --> so you will know how many columns you are selecting.
You'll find your answer here most likely: http://dev.mysql.com/doc/refman/5.0/en/columns-table.html
Write a query off of that that takes a table name param and then query for columns of that table and sum that up.