mysql stored procedure does not find table due to Case - mysql

I'm currently moving my project to production and found an odd situation. The database was (unfortunately) created with object names in lowercase. Now, I'm acting on table all over my 100+ stored procedures/functions, not always keeping in mind the fact that I should use lowercase for table names.
I made a simple test:
select * from mytable ;
yields all the records in the table, whereas:
select * from Mytable ;
returns a "table does not exist" error.
Is there any solution someone could suggest besides going one by one through each and every stored procedure/function and correct the case of the table names?
Thanking in advance for any life-saving suggestion.

From the MySQL documentation on cases in identifiers:
In MySQL, databases correspond to directories within the data
directory. Each table within a database corresponds to at least one
file within the database directory (and possibly more, depending on
the storage engine). Triggers also correspond to files. Consequently,
the case sensitivity of the underlying operating system plays a part
in the case sensitivity of database, table, and trigger names.
I would probably take the time to make everything lower case because it will save you headaches further down the line. If you have a client with a decent editor like MySQL Workbench then you can do these replaces with a quick find and replace.
EDIT:
According to the documentation, you can try setting the lower_case_table_names system variable to 1, which will:
Table names are stored in lowercase on disk and name comparisons are
not case sensitive. MySQL converts all table names to lowercase on
storage and lookup. This behavior also applies to database names and
table aliases.
This might solve your problem if all of the table had been created with lowercase on disk.

Related

MySQL on Ubuntu Case Sensitivity Issues

DB was designed for SQL Server initially. Back then all table names were mixed case. For example, UserTasks.
Hundreds of stored procedures were written on these tables and those stored procedures use mixed case table names.
DB was migrated to MySQL (on Windows) and during that process table names were automatically converted to all lower case but code inside stored procedures was converted to MySQL format without changing the table name cases.
We just migrated to Ubuntu and everything stopped working because MySQL can no longer find those tables used in SQL statements in stored procedures.
Is there a easy way around this? I know the hard way. Open each one of those 550 stored procedures and change table names to lower case one by one.
You should read https://dev.mysql.com/doc/refman/5.7/en/identifier-case-sensitivity.html
Case sensitivity of table names is a complex story on MySQL, because it works on all types of environments: Windows, which is case-insensitive, Unix and Linux, which is case-sensitive, and also MacOS which is sort of a hybrid.
You might be able to use the lower_case_table_names option. I can't be sure, because I don't use that option myself, I don't use Windows, and I seldom use MySQL stored procedures, so I'm not sure how this will interact with the procedure code.
Good luck!

How to use UPPER case in (existing) mySQL names in Windows

Does anyone know HOW I might preserve case in my table names please
(Win 10 using phpMyAdmin,latest xampp distribution). Could this be because xampp is using MariaDB instead of mySQL?
Table names being rewritten to all lowercase.
Read on phpMyAdmin site that to use preserve case I should add:
'set-variable=lower_case_table_names=0'
this stopped mySQL starting with an error message:
[ERROR] c:\xampp\mysql\bin\mysqld.exe: unknown variable 'set-variable=lower_case_table_names=0'
Then after reading an answer here I learned I should use lower_case_table_names=0so aded that to my.ini and still got the same error.
I then spent 20 mins trying to work out where my set-variable=lower_case_table_names=0 was set. (Thought it must be cached or duplicated or something.)
In desperation I deleted the lower_case_table_names=0 and the error disappeared. I put it back and got the
[ERROR] c:\xampp\mysql\bin\mysqld.exe: unknown variable 'set-variable=lower_case_table_names=0' error. IE they seem to be aliases with the error reporting translating. Somewhat irritating.
You should read the documentation bit more carefully, specifically identifier case sensitivity section.
In MySQL, databases correspond to directories within the data
directory. Each table within a database corresponds to at least one
file within the database directory (and possibly more, depending on
the storage engine). Triggers also correspond to files. Consequently,
the case sensitivity of the underlying operating system plays a part
in the case sensitivity of database, table, and trigger names. This
means such names are not case sensitive in Windows, but are case
sensitive in most varieties of Unix.
Value Meaning
0 Table and database names are stored on disk using the
lettercase specified in the CREATE TABLE or CREATE DATABASE statement.
Name comparisons are case sensitive. You should not set this
variable to 0 if you are running MySQL on a system that has
case-insensitive file names (such as Windows or OS X). If you force
this variable to 0 with --lower-case-table-names=0 on a
case-insensitive file system and access MyISAM tablenames using
different lettercases, index corruption may result. 1 Table names are
stored in lowercase on disk and name comparisons are not case
sensitive. MySQL converts all table names to lowercase on storage and
lookup. This behavior also applies to database names and table
aliases. 2 Table and database names are stored on disk using the
lettercase specified in the CREATE TABLE or CREATE DATABASE statement,
but MySQL converts them to lowercase on lookup. Name comparisons are
not case sensitive. This works only on file systems that are not case
sensitive! InnoDB table names are stored in lowercase, as for
lower_case_table_names=1.
To summarise: on windows you should not set lower_case_table_names to 0. If you want to preserve the letter case for table names on windows, then set lower_case_table_names to 2.
The using system variables section explains how to set a system variable in various ways.
Putting lower_case_table_names=2 in your my.ini files allows the use of upper and lower case in tabel names... BUT .... BIG BUT... it does NOT allow you to put upper case letters into EXISTING file names.
The solution is to COPY your table to a new table with the "correct" name.
However as this only changes the appearance of the table names (tables are stored in lower case files) you must use an intermediate table.
EG you want the table name to be HelloWorld but you discover it is stored as helloworld. Add the line above to your my.ini file then make a copy helloworld to a new table, say "helloTemp", delete helloworld copy helloTemp to HelloWorld delete helloTemp and you have a table with HelloWorld as the name.

Migrating from MySQL to DB2 iSeries

So I don't want this thread to be marked as spam, as a previous thread was on this topic was, so I will explain what I have done so far and my issue is and ask if there are any solutions.
I have a MySQL database on my laptop that I need to migrate to DB2 on iSeries. I'm using a tool, I won't say which one because of the spam issue, which allows me to "copy" a table in my MySQL database and "paste" it into my DB2 database.
The issue that I'm having is because the table names and column names contain spaces in the MySQL db, the tool is failing on the paste. I confirmed this by altering one table by replacing the spaces with underscores and the copy worked perfectly. I have over a hundred tables I need to copy over and don't want to have to manually edit every table and column name.
Is there a way to globally replace spaces with underscores in MySQL table names and columns?
Any other ideas? I'm also researching a way to force the query the tool creates to enclose the object names in quotes, but have had no luck so far.
Thanks for any help and suggestions you can provide.
Since Stack Overflow is about helping to solve programming problems, I'm going to ignore the issue of deficiencies in the chosen tool and propose a programming solution to the larger problem - DB2 does not allow spaces in table and column names. You did ask for any suggestions...
Write code that reads the MySQL catalog tables. In DB2 they'd be SYSTABLES, SYSVIEWS, SYSINDEXES, SYSCOLUMNS, etc. Read SYSTABLES and use that as the 'primary' source for the rest of the code. Check the table name; if it has an embedded space, replace it with an underscore. Use SYSCOLUMNS to generate a CREATE TABLE statement that will create the new table (in a new MySQL database?) - also performing space to underscore replacement. After issuing the CREATE TABLE, generate an SQL statement that will INSERT INTO the new table the columns from the old table; again doing the space to underscore substitutions. Once the new table is populated, generate SQL statements to CREATE VIEW, CREATE PROCEDURE, CREATE FUNCTION, etc.
The general idea is that you will completely re-create your MySQL database with table, view and column names that are immediately compatible with DB2 for i so that your tool can do it's thing.
Of course, if you go to that much trouble it'll probably be just as easy to directly CREATE TABLE, etc on the IBM i side rather than go through an intermediate tool that isn't quite what you need.

How to dump database from mysql with sensitive data removed or corrupted?

I am using mysql. Some of the tables contain sensitive data like user names, email addresses, etc. I want to dump the data but with these columns in the table removed or modified to some fake data. Is there any way to do it easily?
I'm using this approach:
Copy contents of sensitive tables to a temporary table.
Clear/encrypt the sensitive columns.
Provide --ignore-table arguments to mysqldump.exe to leave the original tables out.
It preserves foreign key contraints, and you can keep columns that are not sensitive.
The first two actions are contained in a stored procedure that I call before doing the dump. It looks something like this:
BEGIN
truncate table person_anonymous;
insert into person_anonymous select * from person;
update person_anonymous set Title=null, Initials=mid(md5(Initials),1,10), Midname=md5(Midname), Lastname=md5(Lastname), Comment=md5(Comment);
END
As you can see, I'm not clearing the contents of the fields. Instead, I keep a hash. That way, you can still see which rows have the same value, and between exports you can see if something changed or not, without anyone being able to read the actual values.
There is a tool called Jailer that is typically used to export a subset of a database. We use this at work to create a smaller test database from a production backup, with all sensitive data obfuscated.
The GUI is a bit crude, but Jailer is the best alternative I have found so far.
You can simply unselect the sensitive tables or columns and get a full copy of the rest. Jailer also supports obfuscating data during export - you could for instance md5 hash all user names or change all email addresses to user#example.org.
There is a tutorial to get you started.
ProxySQL is another approach.
Here is an article explaining how to obfuscate data with proxysql.
https://proxysql.com/blog/obfuscate-data-from-mysqldump

MySQL Lowercase Table Names in Windows Uppercase names on Unix

I have a a problem whereby my production server runs Unix and my dev server runs MS Windows.
The problem is that Windows is not case sensitive and Unix is. So my table set on the production server uses Uppercase table names ie "Customers" and on Windows the table names are in lowercase "customers".
All this is fine until you need to get data from one box to another and your SQL export says insert into "customers" in lowercase, and presto "Unkown table customers". Because the production server is currently on a shared hosting plan i cant change the settings and install the key that ignores case.
So my question, is there a way to get Windows to convert the tables back to the correct case or is there some setting I can include in the export SQL file so that i can upload data without this problem.
Thanks
UPDATE
Here is what I discovered for anybody else having this issue.
If you have already set up your tables running MySQL on Windows adding
lower_case_table_names=2 to your my.cnf or my.ini file will not change the case of your tables automatically even if they were originally created using uppercase or mixed case names.
CREATE TABLE "MyTable" will create a new table "mytable" not "MyTable" even when lower_case_table_names=2 is set in your my.cnf file.
To get around this problem use this method
Make a copy of your original table
Drop your original table
Rename your copy table using the correct case.
This is the only way it will work. Hope this helps somebody.
Taken from dev.mysql.com:
To avoid data transfer problems arising from lettercase of database or table names, you have two options:
Use lower_case_table_names=1 on all systems. The main disadvantage with this is that when you use SHOW TABLES or SHOW DATABASES, you do not see the names in their original lettercase.
Use lower_case_table_names=0 on Unix and lower_case_table_names=2 on Windows. This preserves the lettercase of database and table names. The disadvantage of this is that you must ensure that your statements always refer to your database and table names with the correct lettercase on Windows. If you transfer your statements to Unix, where lettercase is significant, they do not work if the lettercase is incorrect.
Exception: If you are using InnoDB tables and you are trying to avoid these data transfer problems, you should set lower_case_table_names to 1 on all platforms to force names to be converted to lowercase.
If you plan to set the lower_case_table_names system variable to 1 on Unix, you must first convert your old database and table names to lowercase before stopping mysqld and restarting it with the new variable setting.
There is one easy solution:
Always name your tablenames lowercase.
The universal guiding philosophy of Windows with respect to case is "case-insensitive, case stored". That means Windows never intends to discard your case, so it's a little mysterious why your tables on Windows are lower-case.
Apologies if this is a dumb question, but have you tried renaming the tables on the Windows machine so they have the correct case pattern?