Not able to alter column with Default function in MySQL 5.7 - mysql

Im trying to run this query to mask the contents in the column "audio" but keep getting the error message for wrong syntax
ALTER TABLE test
ALTER COLUMN audio varchar(10) MASKED WITH (FUNCTION = 'default()');
Where am i going wrong here. Pls help

MySQL does not support MASKED WITH syntax for Dynamic Data Masking. That's a proprietary feature of Microsoft SQL Server.
Microsoft SQL Server is a different RDBMS product from MySQL. Both of these products have features and syntax not supported by the other.
In MySQL 5.7, the DEFAULT can be a constant scalar value, or NULL, or CURRENT_TIMESTAMP. Those are the only options (see https://dev.mysql.com/doc/refman/5.7/en/data-type-defaults.html).
In MySQL 8.0, you can now use a constant expression for the default of a column (see https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html).
In both versions, you must use the DEFAULT keyword.
Re your comment:
is there any other way, I can hide this column data for other users other than the root user
You can define a VIEW that excludes columns you want to hide. The view can read the base table, but it does not select the audio column. Users can read the view, but do not grant access to the base table to all users.
MySQL supports granting column-level privileges, but I have never seen anyone use them, and I don't know if they really work.

Related

Datetime error migrating MS Access to MySQL with Workbench

I am trying to migrate an MS Access database to MySQL Server using Workbench, but Workbench generates errors in the SQL CREATE script, which causes some tables to fail to be created. Most are of the following form:
Too-big precision 19 specified for 'TransDate'. Maximum is 6..
SQL Error: 1426
Referring to:
CREATE TABLE IF NOT EXISTS `dbName`.`tblName` (
`ID` INT(10) NOT NULL,
`TransDate` DATETIME(19) NULL,
`ClientID` INT(10) NULL,
...
As you can see, it also generates integer types with deprecated display width syntax, which is something I would like to avoid as well.
How can I make Workbench generate a script that avoids these problems?
EDIT
I am aware that the script can be manually edited in the Create Target Results stage; however there are many tables that have these errors, and I can't see any way to edit them with a text editor, so I am looking for a solution wherein Workbench generates the correct script automatically.
In the Manual Editing tab, I found an option to edit column mappings, which allows you to change multiple columns of the same type across the script all at once. Pick Column Mappings from the drop down window, and right click on a row that corresponds to the type you want to remap. Then choose 'Find and Replace Target Type' and provide the types you want to map.

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).

making mysql 5.7 behave like 5.1

I have migrated from a server running MySQL version 5.1.73 - Source Distribution to a server running 5.7.16-0ubuntu0.16.04.1 - (Ubuntu). Both servers are still up and running.
However, I'm encountering multiple (maddening) errors on queries that used to work, for example:
(Error #1364) Field 'Settings' doesn't have a default value
What is a fancy way of saying I didn't write the query on insert to include Settings because it didn't need a value yet.
So, I figure I'll go in and ALTER that field and give it a default value. MySQL lovingly tells me
#1101 - BLOB, TEXT, .. column 'Settings' can't have a default value
Thank you, MySQL..
So it looks like I'm going to have to refactor code, but this could take some time. What is the easiest way to make MySQL on the new server emulate 5.1.73?
UPDATE: It appears that one can make a LONGTEXT field be NULL (vs. NOT NULL), and then the default will in effect be null. But one cannot have a default that is "empty" or "blank" on a LONGTEXT or similar field. Lesson I'm learning here, be careful about making a skeleton/bare record entry into the db without referencing certain fields like this explicitly; any non-referenced LONGTEXT field will need to be null - which by the way is a reasonable and logical value vs. blank.
This has to do with the change they made in 5.7 to enforce strict SQL mode by default. The default SQL mode in MySQL 5.7 is: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION.
See http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-changes for more information.
You might ask, "why don't they make strict mode optional, but leave it off by default?" The answer is, they did—for about 10 years! It was time to make the next step and enforce strict mode by default. It helps bring MySQL into better SQL compliance and compatibility with other standard RDBMS products.
So how can you turn off strict mode to make it act like the previous, more lax SQL mode? It's easy, put this in your /etc/my.cnf:
sql_mode=NO_ENGINE_SUBSTITUTION
You can also enable that change without restarting mysqld:
mysql> SET GLOBAL sql_mode='NO_ENGINE_SUBSTITUTION';
You probably want to keep NO_ENGINE_SUBSTITUTION on. Engine substitution means for example if you declare a table with ENGINE=InnoDB but the InnoDB storage engine is not enabled for some reason, MySQL will create the table but make it MyISAM silently. This is a bad thing to let happen if you intended it to be InnoDB.

Deleting/Editing rows in MySQL ODBC linked table results in error in MS Access

I am using MS Access 2003 under Windows 7 (64bit), with external linked table at MySQL server (5.0.51a-24+lenny5), connected via MySQL ODBC connector (using 5.1.10, because the newest 5.1.11 is buggy). When I open this table in MS Access and try to delete some records from it, I get following error:
The Microsoft Jet engine stopped the process because you and another
user are attempting to change the same data at the same time.
When I try to edit some records in the table, I get following error:
This record has been changed by another user since you started editing
it. If you save the record, you will overwrite the changes the other
user made.
Copying the changes to the clipboard will let you look at the values
the other user entered, and then paste your changes back in if you
decide to make changes.
However, when I do it via deletion or update query in MS Access, it works fine! I just cannot delete the records directly from the table.
I found out (see the detailed analysis below), that the problem is present when there are double fields with values with a lot of decimal digits. See:
CREATE TABLE `_try4` (
`a` int(11) NOT NULL default '0',
`b` double default NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
insert into _try4 values (1, NULL),(2, 4.532423),(3,10),(4,0),
(5,6.34324),(6, 8.2342398423094823);
The problem is only present when you try to delete/edit the last record (a = 6), otherwise it is OK!
The issue is documented:
http://support.microsoft.com/kb/280730 , proposing these 3 workarounds:
Add a timestamp column to the SQL table. (JET will then use only this field to see if the record has been updated.)
Modify the data type that is in SQL Server to a non-floating point data type (for example, Decimal).
Run an Update Query to update the record. You must do this instead of relying on the recordset update.
However, these 3 workarounds are not satisfactory. Only first could be, but this workaround didn't work - as expected. It probably works only with MS SQL Server.
Are there any other solutions/workarounds for this problem?
Additional details:
The MySQL server is just for me, nobody else is accessing it.
Insertion of new records was working fine.
Primary key is well defined for this table.
Restart of MS Access didn't help.
Deleting the link to the ODBC table and linking it again didn't help either.
Linking the table from brand new Access database didn't help.
Changing the MySQL database engine from MyISAM to InnoDB didn't help either.
There is no problem with permissions, there are all permission for this user#host.
I can normally delete the records from the MySQL console at the server without problem.
Trying to set MySQL Connector ODBC options didn't help: Allow big results, Enable automatic reconnect, Allow multiple statements, Enable dynamic cursors, Force use of forward-only cursors, Don't cache results of forward-only cursors.
I turned on debugging in MySQL ODBC connector, it created myodbc.sql log, but it didn't contain any corresponding queries when editing/deleting (don't know why).
More details about the structure of the linked table would be helpful, but I'll hazard a guess.
I've had a similar problem in both MS Access 2003 and 2010 when I included nullable boolean fields in the SQL Server linked table. Seems JET databases have a problem with nullable nit fields. Check out this answer for more information: https://stackoverflow.com/a/4765810/1428147
I fixed my problem by making boolean fields non-nullable and setting a default value. If your problem is the same as mine, but with MySQL, try doing the same.
I solved here the same issue. The solution was to remove Default Values from decimal fields in the table. I was able to keep decimal data type but just remove the default value I already defined before with 0.0000 and now I set to null and bug fixed.
My workaround was to copy the table data into excel, then use phpadmin to clear the table, then do the editing in excel and copy the 'new' data (ie, all of it, after editing) back to access.

Why can't a text column have a default value in MySQL?

If you try to create a TEXT column on a table, and give it a default value in MySQL, you get an error (on Windows at least). I cannot see any reason why a text column should not have a default value. No explanation is given by the MySQL documentation. It seems illogical to me (and somewhat frustrating, as I want a default value!). Anybody know why this is not allowed?
Windows MySQL v5 throws an error but Linux and other versions only raise a warning. This needs to be fixed. WTF?
Also see an attempt to fix this as bug #19498 in the MySQL Bugtracker:
Bryce Nesbitt on April 4 2008 4:36pm:
On MS Windows the "no DEFAULT" rule is an error, while on other platforms it is often a warning. While not a bug, it's possible to get trapped by this if you write code on a lenient platform, and later run it on a strict platform:
Personally, I do view this as a bug. Searching for "BLOB/TEXT column can't have a default value" returns about 2,940 results on Google. Most of them are reports of incompatibilities when trying to install DB scripts that worked on one system but not others.
I am running into the same problem now on a webapp I'm modifying for one of my clients, originally deployed on Linux MySQL v5.0.83-log. I'm running Windows MySQL v5.1.41. Even trying to use the latest version of phpMyAdmin to extract the database, it doesn't report a default for the text column in question. Yet, when I try running an insert on Windows (that works fine on the Linux deployment) I receive an error of no default on ABC column. I try to recreate the table locally with the obvious default (based on a select of unique values for that column) and end up receiving the oh-so-useful BLOB/TEXT column can't have a default value.
Again, not maintaining basic compatability across platforms is unacceptable and is a bug.
How to disable strict mode in MySQL 5 (Windows):
Edit /my.ini and look for line
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Replace it with
sql_mode='MYSQL40'
Restart the MySQL service (assuming that it is mysql5)
net stop mysql5
net start mysql5
If you have root/admin access you might be able to execute
mysql_query("SET ##global.sql_mode='MYSQL40'");
Without any deep knowledge of the mySQL engine, I'd say this sounds like a memory saving strategy. I assume the reason is behind this paragraph from the docs:
Each BLOB or TEXT value is represented internally by a separately allocated object. This is in contrast to all other data types, for which storage is allocated once per column when the table is opened.
It seems like pre-filling these column types would lead to memory usage and performance penalties.
As the main question:
Anybody know why this is not allowed?
is still not answered, I did a quick search and found a relatively new addition from a MySQL developer at MySQL Bugs:
[17 Mar 2017 15:11] Ståle Deraas
Posted by developer:
This is indeed a valid feature request, and at first glance it might seem trivial to add. But TEXT/BLOBS values are not stored directly in the record buffer used for reading/updating tables. So it is a bit more complex to assign default values for them.
This is no definite answer, but at least a starting point for the why question.
In the mean time, I'll just code around it and either make the column nullable or explicitly assign a (default '') value for each insert from the application code...
"Support for DEFAULT in TEXT/BLOB columns"
is a
feature request in the MySQL Bugtracker (Bug #21532).
I see I'm not the only one who would like to put a default value in a TEXT column.
I think this feature should be supported in a later version of MySQL.
This can't be fixed in the version 5.0 of MySQL,
because apparently it would cause incompatibility and dataloss if anyone tried to transfer a database back and forth between the (current) databases that don't support that feature and any databases that did support that feature.
You can get the same effect as a default value by using a trigger
create table my_text
(
abc text
);
delimiter //
create trigger mytext_trigger before insert on my_text
for each row
begin
if (NEW.abc is null ) then
set NEW.abc = 'default text';
end if;
end
//
delimiter ;
Support for using expression as default values was added to MySQL 8.0.13, released 2018-10-22, and works for TEXT, JSON, BLOB and GEOMETRY.
You still cannot write :
create table foo(bar text default 'baz')
But you can now write:
create table foo(bar text default ('baz'))
Which achieve the same thing.
I normally run sites on Linux, but I also develop on a local Windows machine. I've run into this problem many times and just fixed the tables when I encountered the problems. I installed an app yesterday to help someone out and of course ran into the problem again. So, I decided it was time to figure out what was going on - and found this thread. I really don't like the idea of changing the sql_mode of the server to an earlier mode (by default), so I came up with a simple (me thinks) solution.
This solution would of course require developers to wrap their table creation scripts to compensate for the MySQL issue running on Windows. You'll see similar concepts in dump files. One BIG caveat is that this could/will cause problems if partitioning is used.
// Store the current sql_mode
mysql_query("set #orig_mode = ##global.sql_mode");
// Set sql_mode to one that won't trigger errors...
mysql_query('set ##global.sql_mode = "MYSQL40"');
/**
* Do table creations here...
*/
// Change it back to original sql_mode
mysql_query('set ##global.sql_mode = #orig_mode');
That's about it.
For Ubuntu 16.04:
How to disable strict mode in MySQL 5.7:
Edit file /etc/mysql/mysql.conf.d/mysqld.cnf
If below line exists in mysql.cnf
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Then Replace it with
sql_mode='MYSQL40'
Otherwise
Just add below line in mysqld.cnf
sql_mode='MYSQL40'
This resolved problem.
This is a very old question but still it doesn't seems to have been answered properly. And, my this answer isn't actual answer to the question - "WHY can't a text column have a default value", but as it isn't possible to write long text in comment, and as my comment could help someone to prevent the error, here it is as a separate answer:
Some are saying that the error is occurring because of OS - Windows-Linux; but this isn't directly related to OS. (However, there may be differences in default settings of MySQL within different installers for different OSes, I am not sure.)
The main reason is the flag STRICT_TRANS_TABLES for sql_mode setting. if a value is not specified in INSERT statement for TEXT datatype column and if the flag exist in the sql_mode setting then MySQL is reporting an error; and if the flag doesn't exist then MySQL is only reporting a warning and inserts the record.
So, to prevent this error, one can remove the STRICT_TRANS_TABLES from sql_mode setting of MySQL. (He my need to reset the mode to the previous value if it can affect other operations on the database.)
According to the documentation of SQL mode in MySQL ...
For STRICT_TRANS_TABLES, MySQL converts an invalid value to the closest valid value for the column and inserts the adjusted value. If a value is missing, MySQL inserts the implicit default value for the column data type. In either case, MySQL generates a warning rather than an error and continues processing the statement. Implicit defaults are described in Section 11.6, “Data Type Default Values”.
... and documentation of Data Type Default Values ...
The BLOB, TEXT, GEOMETRY, and JSON data types cannot be assigned a default value.
... TEXT column can not have a default value, but if STRICT_TRANS_TABLES is removed from sql_mode then MySQL inserts empty string '' if no value is specified for TEXT column in INSERT statement.