Meaning of 'Default Database' in MySQL - mysql

I was going through the specifications for loading data into and from MySQL tables at dev.mysql, when I came across the specifications for the local option in the load infile data command. It says that if local is not used, then if a file name with no leading components is given, the server looks for the file in the database directory of the default database. Can anyone tell me what is meant by default database here, and how to set one? Can it be set from within MySQL itself, or through some server directive?

The default database is the one you called with a USE clause or specified at login time. If you use SELECT * FROM tablename as opposed to SELECT * FROM databasename.tablename you also use the default database.
Edit
Just to make that clear: The default database is not a static thing - it is defined only for a defined point in time on a defined session - e.g. such as the PIT and session where you start the load data infile command.

Generally the default database will be specified in a database param under the [client] header in your config (my.ini/my.cnf/etc), like such:
[client]
database = name_of_default_db

Related

How to disable DB prefix name in mysql 6.3 Workbench

I want to disable database prefix name while executing queries in MySQL.
I am using MySQl Workbench 6.3 CE.
For Example : SELECT * FROM test_db.test_table;
I want to remove test_db prefix.
If you're using MySQL workbench, in the lefthand pane, there is a list of available databases. If you're only using one, you can right click on it and select "set as default schema", then any queries you run in that MySQL session will no longer need to be prefixed with the DB name. However, if you want to query another DB in the same session, you will have to append that DB's name as a prefix, or do the same process, and set that DB as the default schema.
See this link for pretty pictures and a full description: https://www.quackit.com/mysql/tutorial/mysql_default_database.cfm
You have to tell it what database to use .. So you do it the way you are describing. .. Or you tell MySQL which database to use BEFORE the SELECT IE
use test_db;
SELECT * FROM test_table;
They way MySQL works is that you either explicitly state which schema a specific DB object is in (e.g. a table) or it uses the current default schema. If you don't have a default schema set and don't use fully qualfied names, you will get an error from MySQL saying that you have to define a default schema first.
So what you want to accomplish is impossible. Either set a default schema (it's a per connection setting, so you can set it once and use with your other queries as long as you keep the connection open) or fully qualify your DB objects (which is the most flexible approach and also avoids certain ambiquities, like same named tables in different schemas).

How to store files in MySQL database using MySQL Workbench?

I'm trying to store .html files in a MySQL database (using MySQL Workbench). At the moment I'm trying to do load_file('filepath') so the contents of the .html file can be read and converted to string and that string will be stored in the table in the DB. But the problem is that it seems to always return null so I can't check if it's actually working.
I know there are 4 criteria to pass for load_file to work but I don't know which scripts I have to execute to grant the privileges. Since I'm trying to convert the contents of the file to string, maybe there is another way more efficient to store the whole .html file into the DB and if yes could anyone show me how to do this? My MySQL server has a username of root and working on Mac OS.
The load_file function says that:
To use this function, the file must be located on the server host, you must specify the full path name to the file, and you must have the FILE privilege. The file must be readable by all and its size less than max_allowed_packet bytes. If the secure_file_priv system variable is set to a nonempty directory name, the file to be loaded must be located in that directory.
So there are a number of conditions to check if you actually can load the file. Start by checking if your user has the FILE privilege and that the file is accessible by your MySQL server.
For people who's looking for, this is how I did it.
I have a table as
CREATE TABLE `test` (
`ID` int(11) DEFAULT NULL,
`UPLOAD_FILE` mediumblob
);
and I save a file smiley.jpg as
INSERT INTO test (`ID`, `UPLOAD_FILE`) VALUES ('1', LOAD_FILE('E:/smiley.jpg'));

Turn off LOAD DATA INFILE or INTO OUTPUT

As a security minded person, in the off chance that an SQL injection ever happens I'd like to minimize the damage caused. One such possibility is that there are queries that can read and write information to a file on the local file system. This is clearly a major issue in the case of a security breach, and the usage for these commands is fairly limited in day to day usage. Optionally, it could be turned on for an isolated period of time in case I have the need for import and exporting data, but I would like to have it turned off explicitly any other time. No amount of googling or skimming the MySQL manual has led me to a specific setting that allows me to disable this option.
I know I could easily just revoke the privilege for all users, but I'd like a simpler solution that by default increases my security (at least in this specific case).
Does anyone know of any setting or way to deactivate any file interactions in MySQL?
Thanks!
http://dev.mysql.com/doc/refman/5.6/en/load-data.html says:
Also, to use LOAD DATA INFILE on server files, you must have the FILE privilege.
http://dev.mysql.com/doc/refman/5.6/en/select-into.html says:
The SELECT ... INTO OUTFILE 'file_name' form of SELECT writes the selected rows to a file. The file is created on the server host, so you must have the FILE privilege to use this syntax.
You can also set the secure_file_priv config variable:
By default, this variable is empty. If set to the name of a directory, it limits the effect of the LOAD_FILE() function and the LOAD DATA and SELECT ... INTO OUTFILE statements to work only with files in that directory.
In Percona Server, secure_file_priv has an additional usage:
When used with no argument, the LOAD_FILE() function will always return NULL. The LOAD DATA INFILE and SELECT INTO OUTFILE statements will fail with the following error: “The MySQL server is running with the –secure-file-priv option so it cannot execute this statement”.

How can I edit a view in MySQL Workbench without it auto prefixing a database name to the tables/views used

When I create a view, I create it in the context of the default database. So none of my references to table have a prefix which explicitly specify a database. However, when I edit a view in Workbench it automatically adds the database prefix!
I don't want the database prefix because when I restore a database under a different name it causes the restore to fail.
Is this possible to stop the prefixing in a view edit or there another way to get round the restore issue?
see https://bugs.mysql.com/bug.php?id=85176
The mysql 8.0.3 or above has been fixed
That's not possible. Views are stored in specific databases, not in some space "above" all databases. Consider following...
use playground_a; /*or whatever database*/
create view view_whatever as
select * from table_whatever;
use playground_b;
select * from view_whatever; /*here you will get an error that view_whatever does not exist*/
select * from playground_a.view_whatever; /*this works*/
That's why there will always be database prefixes in the view definition.
The only possibility I see, would be to use a stored procedure with a database name as parameter. In the procedure you'd use a prepared statement to execute a concated string of your query and the database name parameter. Of course this comes with downsides, like i.e. you can't add a where clause easily.
Creating the view without explicitely specifying a schema is a convenience feature. Behind the scenes the view is still saved in a specific schema (the default one in this case). When editing the source code is retrieved from the server which returns the real code (including the schema qualification). Hence already when you send the view code the association happens and cannot be removed again later.
Here is the command I use to create the backup:
mysqldump -u xxxxxx -pxxxxxx --routines database_a | gzip -9 > $FULLGZIPPATH
If you aren't easily able to update to MySQL 8.X then a workaround I've implemented was a post-processing step performed on the dump file itself prior to importing. I just remove the explicit prefixed db name, since the import process / view creation doesn't need it.
PowerShell -Command ^
"filter replace-dbname { $_ -replace '`<DB_NAME>`.`', '`' }"^
"Get-Content dump.sql -ReadCount 10 | replace-dbname | Add-Content replaced_dump.sql"
I've used PowerShell since I'm on Windows, but any scripting language will do. The only notes are that:
You'll need to do the replacement a-few-lines-at-a-time if you can't afford to read the entire dump into memory. Our dumps are about 11GB, which'd be a strain on our testing server's resources.
In my script I'm not doing an in-place string replacement, so it'll create a new dump file replaced_dump.sql alongside the original dump.sql. For me this was useful for diagnostics, because it meant if there was an issue, I didn't have to dump it again. Again, depending on your dump/disk size this might be an issue.
If your database happens to have `<DB_NAME>`.` as content in something like a text-field, this basic approach will also remove the string there as well.

Select from second MySQL Server

I would like to select data from a second MySQL database in order to migrate data from one server to another.
I'm looking for syntax like
SELECT * FROM username:password#serverip.databaseName.tableName
Is this possible? I would be able to do this in Microsoft SQL Server using linked servers, so I'm assuming it's possible in MySQL as well.
You can create a table using FEDERATED storage engine:
CREATE TABLE tableName (id INT NOT NULL, …)
ENGINE=FEDERATED
CONNECTION='mysql://username:password#serverip/databaseName/tableName'
SELECT *
FROM tableName
Basically, it will serve as a view over the remote tableName.
There are generally two approaches you can take, although neither of them sound like what you're after:
Use replication and set up a master/slave relationship between the two databases.
Simply dump the data (using the command line mysqldump tool) from the 1st database and import it into the 2nd.
However, both of these will ultimately migrate all of the data (i.e.: not a subset), although you can specify specific table(s) via mysqldump. Additionally, if you use the mysqldump approach and you're not using InnoDB you'll need to ensure that the source database isn't in use (i.e.: has integrity) when the dump is created.
You can't do this directly, but as someone else alluded to in a comment, you can use mysqldump to export the contents of a table as a SQL script.
At that point you could run the script on the new server to create the table, or if more manipulation of the data is required, import that data into a table with a different name on the new server, then write a query to copy the data from there.