This question already has answers here:
How to best display in Terminal a MySQL SELECT returning too many fields?
(12 answers)
Closed 3 years ago.
I am using mysql command line client in terminal emulator lxterminal in Ubuntu. When I run the following command:
mysql> select * from routines where routine_name = "simpleproc";
The output is a mess:
But if I copy and paste it here, the output shows me a nice table:
mysql> select * from routines where routine_name = "simpleproc";
+---------------+-----------------+----------------+--------------+--------------+-----------+--------------------------+------------------------+-------------------+---------------+--------------------+--------------------+----------------+----------------+--------------+--------------------------------------------------------+---------------+-------------------+-----------------+------------------+-----------------+----------+---------------+---------------------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------+-----------------+----------------+----------------------+----------------------+--------------------+
| SPECIFIC_NAME | ROUTINE_CATALOG | ROUTINE_SCHEMA | ROUTINE_NAME | ROUTINE_TYPE | DATA_TYPE | CHARACTER_MAXIMUM_LENGTH | CHARACTER_OCTET_LENGTH | NUMERIC_PRECISION | NUMERIC_SCALE | DATETIME_PRECISION | CHARACTER_SET_NAME | COLLATION_NAME | DTD_IDENTIFIER | ROUTINE_BODY | ROUTINE_DEFINITION | EXTERNAL_NAME | EXTERNAL_LANGUAGE | PARAMETER_STYLE | IS_DETERMINISTIC | SQL_DATA_ACCESS | SQL_PATH | SECURITY_TYPE | CREATED | LAST_ALTERED | SQL_MODE | ROUTINE_COMMENT | DEFINER | CHARACTER_SET_CLIENT | COLLATION_CONNECTION | DATABASE_COLLATION |
+---------------+-----------------+----------------+--------------+--------------+-----------+--------------------------+------------------------+-------------------+---------------+--------------------+--------------------+----------------+----------------+--------------+--------------------------------------------------------+---------------+-------------------+-----------------+------------------+-----------------+----------+---------------+---------------------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------+-----------------+----------------+----------------------+----------------------+--------------------+
| simpleproc | def | test | simpleproc | PROCEDURE | | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | SQL | BEGIN
SELECT COUNT(*) INTO param1 FROM CUSTOMERS1;
END | NULL | NULL | SQL | NO | CONTAINS SQL | NULL | DEFINER | 2018-01-12 15:18:20 | 2018-01-12 15:18:20 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | | root#localhost | utf8 | utf8_general_ci | latin1_swedish_ci |
+---------------+-----------------+----------------+--------------+--------------+-----------+--------------------------+------------------------+-------------------+---------------+--------------------+--------------------+----------------+----------------+--------------+--------------------------------------------------------+---------------+-------------------+-----------------+------------------+-----------------+----------+---------------+---------------------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------+-----------------+----------------+----------------------+----------------------+--------------------+
1 row in set (0.01 sec)
I wonder if it is possible to view the output in a terminal emulator as a nice table like this one?
Using mysql's ego command
From mysql's help command:
ego (\G) Send command to mysql server, display result vertically.
So by appending a \G to your select, you can get a very clean vertical output:
mysql> select * from routines where routine_name = "simpleproc" \G
Using a pager
You can tell MySQL to use the less pager with its -S option that chops wide lines and gives you an output that you can scroll with the arrow keys:
mysql> pager less -S
Thus, next time you run a command with a wide output, MySQL will let you browse the output with the less pager:
mysql> select * from routines where routine_name = "simpleproc";
If you're done with the pager and want to go back to the regular output on stdout, use this:
mysql> nopager
You can try also adjusting the font size of the terminal but displaying the output vertically should be clear if all doesn't.
use the /G option to run the query i.e
mysql> select * from routines where routine_name = "simpleproc" \G
If you are running on Ubuntu you can use the bash shell, it looks nice and not messed up like this.
Related
Were attempting to migrate some mysql servers to MariaDB on a new AWS (amazon-linux-2) instance.
After creating a new instance and installing mariadb we've dumped the old database via
mysqldump ... --add-drop-database --triggers --routines --events
and imported into the new system using
mysql -u root < dump.sql
The database has a table defined with mixture of uppercase and lower case columns e.g COLUMN1,COLUMN2,column3,etc
The original database, via mysqld -V, is mysqld Ver 14.14 Distrib 5.5.62, for Linux (x86_64)
The new database is, via mysqld -V, is mysqld Ver 15.1 Distrib 5.5.64-MariaDB, for Linux (x86_64)
installed with yum install mariadb-server
I've verified the schema's columns match for the table in question.
The accessing application queries the table with a select statement requesting the columns as lowercase.
(I've connected a local application and tested executing the same query against both database)
e.g. SELECT column1,column2,column3,etc from TABLE1 where ..
The results from the query from the original database respect the casing in the "select" statement from the application, however in the new mariadb database, the query results match the column casing as defined in the table.
Is there a setting that can be applied that will cause the result column names to respect the casing in the "SELECT" statement, and therefore cause the result column names returned by the same select statement in both databases to match?
A testcase under MariaDB and Mysql
select cname from (select s.CName from (select 'A' as CNAME) s) t;
Under MariaDB the result set column casing matches the column from the intermediary temp table.
With the same query using the source mysql database,
The result set column name's casing matches the casing in the select statement
It's always a bad practice not to use coding styles for SQL and mixing lowercase, uppercase or mixed case identifiers ("It was hard to write, therefore it should be hard to read"). There are several coding style guidelines, e.g. SQL Style Guide.
Beside that, you should also consider to upgrade to a more recent version of MariaDB/MySQL. MariaDB 5.5 will be eoled in 3 months.
But back to your problem:
Column identifiers are case insensitive, therefore the optimizer recognizes that your SQL statement can be simplified, in more recent versions of MariaDB the EXPLAIN EXTENDED and SHOW WARNINGS commands will give you more information:
MariaDB [(none)]> select version();
+--------------------------+
| version() |
+--------------------------+
| 10.5.1-MariaDB-debug-log |
+--------------------------+
MariaDB [(none)]> explain extended select cname from (select s.CName from (select 'A' as CNAME) s) t;
+------+-------------+------------+--------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+------+-------------+------------+--------+---------------+------+---------+------+------+----------+----------------+
| 1 | PRIMARY | <derived3> | system | NULL | NULL | NULL | NULL | 1 | 100.00 | |
| 3 | DERIVED | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+------+-------------+------------+--------+---------------+------+---------+------+------+----------+----------------+
2 rows in set, 1 warning (0.00 sec)
MariaDB [(none)]> show warnings;
+-------+------+------------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------------+
| Note | 1003 | /* select#1 */ select 'A' AS `CName` from dual |
+-------+------+------------------------------------------------+
As you can see, the statement was optimized and transformed to select 'A' AS `CName` from dual.
Obviously in MariaDB 5.5 the optimizer was already more modern than the MySQL optimizer, but in recent version of MySQL you will get the same result:
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.13 |
+-----------+
1 row in set (0,00 sec)
mysql> explain select cname from (select s.CName from (select 'A' as CNAME) s) t;
+----+-------------+------------+------------+--------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+--------+---------------+------+---------+------+------+----------+----------------+
| 1 | PRIMARY | <derived3> | NULL | system | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| 3 | DERIVED | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No tables used |
+----+-------------+------------+------------+--------+---------------+------+---------+------+------+----------+----------------+
2 rows in set, 1 warning (0,00 sec)
mysql> show warnings;
+-------+------+------------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------------+
| Note | 1003 | /* select#1 */ select 'A' AS `CName` from dual |
+-------+------+------------------------------------------------+
I have the following two Triggers
cascadeUserInsertionToRecommendations_tbl
and
afterinsertiontousers
Now below, just for completeness, is the result of "show triggers;"
+-------------------------------------------+--------+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------+---------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+-------------------------------------------+--------+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------+---------+----------------------+----------------------+--------------------+
| cascadeUserInsertionToRecommendations_tbl | INSERT | users_tbl | INSERT INTO recommendations_tbl(recommendation_userid, recommendation_category, recommendation_manufacturer) VALUES(NEW.user_id, 'diverse', 'diverse') | AFTER | 2019-09-02 12:32:46.19 | NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION | # | latin1 | latin1_swedish_ci | latin1_swedish_ci |
| afterinsertiontousers | INSERT | users_tbl | INSERT INTO recommendations_tbl(recommendation_userid, recommendation_category, recommendation_manufacturer) VALUES(NEW.user_id, DEFAULT, DEFAULT) | AFTER | 2019-09-02 15:48:39.52 | NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION | # | latin1 | latin1_swedish_ci | latin1_swedish_ci |
+-------------------------------------------+--------+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------+--------+------------------------+-----------------------------------------------------+---------+----------------------+----------------------+--------------------+
Now the problem is that I just cant drop them :/
When I'm on foundationtests, the database where I created the triggers like so:
CREATE TRIGGER afterinsertiontousers
-> AFTER INSERT ON users_tbl
-> FOR EACH ROW
-> INSERT INTO recommendations_tbl(recommendation_userid, recommendation_category, recommendation_manufacturer) VALUES(NEW.user_id, DEFAULT, DEFAULT);
Query OK, 0 rows affected (0.016 sec)
this is what happens:
MariaDB [foundationtests]> DROP TRIGGER users_tbl.cascadeUserInsertionToRecommendations_tbl;
ERROR 1360 (HY000): Trigger does not exist
I already swapped to information_schema DB and deleted the above Trigger there. However, it still shows up here AND it still does its job, which it shouldnt...
I read about having to use "db5" on multiple other threads on SO, but I can't access this DB neither does it show up in my list of DBs when using "show databases";
So I'm somehow clueless on what I am missing Oo
GOAL: to output all SQL queries and their outputs into a text file
SQL CODE:
\W /*enable warnings*/
USE bookdb; /*doesn't exist because I WILL DROP DATABASE booksdb BEFORE RUNNING THIS SCRIPT (to avoid duplicate entry errors from testing out the queries during the assignment)*/
/* Query 0 */
SELECT user(), current_date(), version(), ##sql_mode\G
/*Query 1*/
CREATE DATABASE IF NOT EXISTS bookdb;
Use bookdb;
/*QUERY 2*/
CREATE TABLE books (
isbn CHAR(10),
author VARCHAR(100) NOT NULL,
title VARCHAR(128) NOT NULL,
price DECIMAL(7 , 2 ) NOT NULL,
subject VARCHAR(30) NOT NULL,
PRIMARY KEY (isbn)
)ENGINE = INNODB;
/*QUERY 3*/
INSERT INTO books
VALUES ('0345377648', 'Anne Rice', 'Lasher', 14.00, 'FICTION');
INSERT INTO books
VALUES ('1557044287','Ridley Scott','Gladiator',26.36,'FICTION');
INSERT INTO books
VALUES ('0684856093', 'Sean Covey', 'The 7 Habits', 12, 'CHILDREN');
/*QUERY 4*/
SHOW TABLES;
/*QUERY 5*/
DESC books;
/*QUERY 6*/
SELECT * FROM books;
/*QUERY 7*/
SELECT ISBN, title, price FROM books;
COMMANDS FROM SQL PROMPT:
mysql> tee /my_scripts/yourname_assignment1.txt
mysql> source /my_scripts/yourname_assignment1.sql
mysql> notee
RESULTING assignment1.txt FILE:
user(): root#localhost
current_date(): 2016-09-25
version(): 5.7.15-0ubuntu0.16.04.1
##sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_ FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
1 row in set (0.00 sec)
Query OK, 1 row affected (0.00 sec)
Database changed
Query OK, 0 rows affected (0.32 sec)
Query OK, 1 row affected (0.06 sec)
Query OK, 1 row affected (0.04 sec)
Query OK, 1 row affected (0.08 sec)
+------------------+
| Tables_in_bookdb |
+------------------+
| books |
+------------------+
1 row in set (0.00 sec)
+---------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| isbn | char(10) | NO | PRI | NULL | |
| author | varchar(100) | NO | | NULL | |
| title | varchar(128) | NO | | NULL | |
| price | decimal(7,2) | NO | | NULL | |
| subject | varchar(30) | NO | | NULL | |
+---------+--------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
+------------+--------------+--------------+-------+----------+
| isbn | author | title | price | subject |
+------------+--------------+--------------+-------+----------+
| 0345377648 | Anne Rice | Lasher | 14.00 | FICTION |
| 0684856093 | Sean Covey | The 7 Habits | 12.00 | CHILDREN |
| 1557044287 | Ridley Scott | Gladiator | 26.36 | FICTION |
+------------+--------------+--------------+-------+----------+
3 rows in set (0.00 sec)
+------------+--------------+-------+
| ISBN | title | price |
+------------+--------------+-------+
| 0345377648 | Lasher | 14.00 |
| 0684856093 | The 7 Habits | 12.00 |
| 1557044287 | Gladiator | 26.36 |
+------------+--------------+-------+
3 rows in set (0.00 sec)
mysql> notee
As you can see, my queries are executed without errors (ie. they are coming out correctly), but the output is not listing the queries themselves.
My professor's "example.txt" file includes the queries that are listed in the assignment1.sql file. In other words, his output apparently includes his queries in the SQL file where my output does not. How do you change the "tee" command to include the queries? Did my professor simply manually edit a copy of the file or am I missing something?
I realize that if I manually enter the commands, my output will look more like his (ie. with the queries), but that's not the way he explained this assignment.
I'm running the latest x64 Ubuntu OS if that might have an effect on the SQL. I'm new to this. I've thoroughly searched online for this specific issue, but no one has this one listed.
Thank you.
ASSIGNMENT DIRECTIONS IF THIS CLARIFIES ANYTHING:
Run the following command:
mysql -u root –p --force --comments –vvv
Use the tee command to put your output in a text file to submit.
mysql> tee c:/my_scripts/yourname_assignment1.txt
Run the SQL script hibrahim_assignment1.sql
mysql> source c:\my_scripts\yourname_assignment1.sql
Type in notee to stop the tee command.
mysql> notee
I fixed it. It was because my Linux machine was not giving permissions correctly. The command
mysql -u root -p --force --comments -vvv
required elevation (and didn't require root). I guess I was missing the --force --comments -vvv hence the queries and comments not being included. So for future reference, you'll need elevation. Furthermore, I didn't need to specify root. So the resulting command is
sudo mysql --force --comments -vvv
Suppose I have a table with the following content:
mysql> select * from test;
+----+------+
| id | val |
+----+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 2 |
+----+------+
8 rows in set (0.00 sec)
mysql>
Now I run erroneous SQL query with group by clause and without any aggregation on id column and get wrong results:
mysql> select id, val from test group by val;
+----+------+
| id | val |
+----+------+
| 1 | 1 |
| 5 | 2 |
+----+------+
2 rows in set (0.00 sec)
mysql>
Can mysql client or probably some other tool validate this query and issue error or warning on using group by without aggregation?
Yes, you can do this:
To disable the MySQL GROUP BY extension, enable the ONLY_FULL_GROUP_BY
SQL mode.
mysql> SET sql_mode = 'ONLY_FULL_GROUP_BY';
See the documentation here. Also, this section on server modules may help.
By default, the SQL Mode ONLY_FULL_GROUP_BY is set to disable. And that is the reason why your query did run without throwing any exceptions. If you don't want that behavior enable the ONLY_FULL_GROUP_BY mode,
ONLY_FULL_GROUP_BY
Setting the SQL Mode
You can set the default SQL mode by starting mysqld with the --sql-mode="modes" option, or by using sql-mode="modes" in my.cnf (Unix operating systems) or my.ini (Windows). modes is a list of different modes separated by comma (“,”) characters.
You can change the SQL mode at runtime by using a SET [GLOBAL|SESSION] sql_mode='modes' statement to set the sql_mode system value. ex: SET sql_mode = 'ONLY_FULL_GROUP_BY'
I'm looking for a way to list all views in a database.
Initially I found and tried an answer on the MySQL forums:
SELECT table_name
FROM information_schema.views
WHERE information_schema.views.table_schema LIKE 'view%';
How ever this doesn't work, returning an empty set. (I know they're in there!)
These also fail:
mysql> use information_schema;
Database changed
mysql> select * from views;
ERROR 1102 (42000): Incorrect database name 'mysql.bak'
mysql> select * from tables;
ERROR 1102 (42000): Incorrect database name 'mysql.bak'
Why isn't this working?
SHOW FULL TABLES IN database_name WHERE TABLE_TYPE LIKE 'VIEW';
MySQL query to find all views in a database
Here's a way to find all the views in every database on your instance:
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.tables
WHERE TABLE_TYPE LIKE 'VIEW';
To complement about to get more info about a specific view
Even with the two valid answers
SHOW FULL TABLES IN your_db_name WHERE TABLE_TYPE LIKE 'VIEW';
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.TABLES
WHERE TABLE_TYPE LIKE 'VIEW' AND TABLE_SCHEMA LIKE 'your_db_name';
You can apply the following (I think is better):
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA LIKE 'your_db_name';
is better work directly with information_schema.VIEWS (observe now is VIEWS and not TABLES anymore), thus you can retrieve more data, use DESC VIEWS for more details:
+----------------------+---------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+---------------------------------+------+-----+---------+-------+
| TABLE_CATALOG | varchar(64) | YES | | NULL | |
| TABLE_SCHEMA | varchar(64) | YES | | NULL | |
| TABLE_NAME | varchar(64) | YES | | NULL | |
| VIEW_DEFINITION | longtext | YES | | NULL | |
| CHECK_OPTION | enum('NONE','LOCAL','CASCADED') | YES | | NULL | |
| IS_UPDATABLE | enum('NO','YES') | YES | | NULL | |
| DEFINER | varchar(93) | YES | | NULL | |
| SECURITY_TYPE | varchar(7) | YES | | NULL | |
| CHARACTER_SET_CLIENT | varchar(64) | NO | | NULL | |
| COLLATION_CONNECTION | varchar(64) | NO | | NULL | |
+----------------------+---------------------------------+------+-----+---------+-------+
For example observe the VIEW_DEFINITION field, thus you can use in action:
SELECT TABLE_SCHEMA, TABLE_NAME, VIEW_DEFINITION
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA LIKE 'your_db_name';
Of course you have more fields available for your consideration.
select * FROM information_schema.views\G;
This will work.
USE INFORMATION_SCHEMA;
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.tables
WHERE TABLE_TYPE LIKE 'VIEW';
Try moving that mysql.bak directory out of /var/lib/mysql to say /root/ or something. It seems like mysql is finding that and it may be causing that ERROR 1102 (42000): Incorrect database name 'mysql.bak' error.
The error your seeing is probably due to a non-MySQL created directory in MySQL's data directory. MySQL maps the database structure pretty directly onto the file system, databases are mapped to directories and tables are files in those directories.
The name of the non-working database looks suspiciously like someone has copied the mysql database directory to a backup at some point and left it in MySQL's data directory. This isn't a problem as long as you don't try and use the database for anything. Unfortunately the information schema scans all of the databases it finds and finds that this one isn't a real database and gets upset.
The solution is to find the mysql.bak directory on the hard disk and move it well away from MySQL.
If you created any view in Mysql databases then you can simply see it as you see your all tables in your particular database.
write:
--mysql> SHOW TABLES;
you will see list of tables and views of your database.
Another way to find all View:
SELECT DISTINCT table_name FROM information_schema.TABLES WHERE table_type = 'VIEW'