MySQL/MariaDB Configure Warnings to throw Errors - mysql

I need MySQL/MariaDB to throw error messages instead of warning messages.
Reason: In my development environment, warnings are ignored in SQL/PHP (and both SQL and PHP continue processing), therefore I can't detect any issues when testing. In production, however, all warnings crash the query, thus terminating the API, and returning a "failure" message to users.
This is a very bad result and caused many headaches in the past.
Here is a very specific scenario that caused many problems:
I have a table "testtable" with two columns "pk" and "bRequiredBoolean", where pk is the primary key (thus auto increments) and bRequiredBoolean HAS NO DEFAULT VALUE:
CREATE TABLE `test`.`testtable` ( `pk` INT NOT NULL AUTO_INCREMENT , `bRequiredBoolean` BOOLEAN NOT NULL , PRIMARY KEY (`pk`)) ENGINE = InnoDB;
In my development server, I can run the following query:
INSERT INTO `testtable`() VALUES ()
and receive the following warning:
Warning: #1364 Field 'bRequiredBoolean' doesn't have a default value
In my development server, the entry IS INSERTED and the API continues executing.
In my production server, the entry ISN'T INSERTED and the API crashes.
I know that the development/testing servers should be identical to prevent issues like this, but I currently don't have the funds for extra licenses, so I would like an alternative solution to throw error messages instead of warnings to catch scenarios like the one mentioned above.
Important note: I don't want to insert any extra code within each query, I'd prefer to edit some configuration file. For instance, I don't want to add the following code TO EVERY SINGLE QUERY:
SHOW COUNT(*) WARNINGS
I'd rather edit some configuration file so it will always throw an error, even if I do ad-hoc queries directly through the GUI.
I found other similar questions, but nobody has responded to those threads:
MariaDB shows warnings instead of errors
Throw error on mysql warning pdo
Any help is much appreciated.

Thanks to Barmar's comment, I found the solution to my problem.
You can check your SQL_Mode via:
SELECT ##SQL_MODE;
Apparently, there is a SQL_Mode setting that specifically throws errors for all warnings called "Traditional"
You can view the official mySQL website for more info regarding SQL_Mode values: https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-full
So I ran the following query:
SET GLOBAL sql_mode = 'TRADITIONAL';
After running the query, I executed the same query as before:
INSERT INTO `testtable`() VALUES ()
and received the following error:
Error
SQL query: Copy
INSERT INTO `testtable`() VALUES ();
MySQL said: Documentation
#1364 - Field 'bRequiredBoolean' doesn't have a default value
This is exactly what I needed. Thank you so much #Barmar!

Related

sequelize you are using sql safe update error

I am getting this error randomly . I am deleting from activeusers table on the basis of username it gives me error sometime and works smoothly sometime.
here is my code for deleting
let say
data={nickname:'asad',id:1}
activeusers.destroy({where:{username:data.nickname} }).then(res=>{
});
I have turn off the sql safe update from sql workbench but problem still exists
how can i permanently get rid from this error
This is a common problem with updates in MySQL. Here is your query:
DELETE FROM ActiveUsers WHERE username = 'mazhar.hayat#ibexglobal.com'
The error stems from that you are not using a primary key column in the WHERE clause. You would also see this error if you had no WHERE clause at all. MySQL has a mode which views a DML query like this as unsafe, because it is broad and runs the risk of corrupting your data.
There is a hack solution to this which might work. You could modify the query to mention the primary key column as follows:
DELETE
FROM ActiveUser
WHERE username = 'mazhar.hayat#ibexglobal.com' AND id=id
This might spoof MySQL into thinking the query is safe, because it mentions the primary key column id in the WHERE clause.
But what I would recommend to you is turning off safe updates mode directly in MySQL. Edit your startup script and make sure that --safe-updates and --i-am-a-dummy are not mentioned in the script.
Edit:
If you wanted to handle this from destroy, then the query option is the only option:
Post.findAll(
{ where: ["username = ? AND id = id", data.nickname] }
).success()

SQL Mode Is NO_UNSIGNED_SUBTRACTION But Still Getting Out of Range Error

After upgrading a client from MySQL 5.4 to 5.7 I started getting "BIGINT UNSIGNED value is out of range..." errors. I edited my.cnf and set sql_mode = "NO_UNSIGNED_SUBTRACTION" and used SHOW VARIABLES to ensure it was indeed using that mode. That did fix the initial problem in the application but today an unsigned int column is throwing the same error (BTW inventory is 2)...
UPDATE table SET inventory = inventory - 1
I don't understand why since I thought the new sql_mode would revert behavior to pre 5.5? I don't want to start casting everything in my statements just to make simple arithmetic work so the logical solution in my mind is just to convert all of my unsigned int cols to signed ints with the exception of primary auto increment keys.
Is this the best solution to escape these out of range errors?
I did some more digging and found my answer and wanted to share here for anyone stuck on this in the future. The SQL mode NO_UNSIGNED_SUBTRACTION was indeed working and had not reverted for this table/column. In short, the problem was that there was a trigger on that table and I discovered from a somewhat related MySQL bug report from 2009 that as stated in user comments by Davi Arnaut that triggers and prepared statements use the SQL mode that was in use when they were created... aaah! So, I redefined the trigger and everything works as expected.

MySQL- Insert a record with empty primary key, works on one server, not the other

I have a table in a MySQL Server (version 5.5.27, installed with EasyPHP for development), it has an ID with Auto_Increment, and it's data type is INT(11).
When i try to insert a record, using this statement, it works.
insert into factclientes (IDFactClientes, IDTercero, SubTotal, IVA, Total)
values ('', '3', '2500.00', '400.00', '2900.00')
ON DUPLICATE KEY UPDATE IDTercero = values(IDTercero),
SubTotal = values(SubTotal),
IVA = values(IVA),
Total = values(Total)
But when i try to insert that same record on my production server (version 5.6.17, installed independently on another machine) it throws an error:
Incorrect integer value: '' for column 'IDFactClientes' at row 1
I know it is because the primary key ID 'IDFactClientes' has an empty value. I do this because i use the same statement to INSERT and to UPDATE. If my program doesn't know and doesn't specify the IDFactClientes, i want a new record, if my program knows the ID already, and it's specified i want the record to be updated.
The weird thing is that it works on my dev machine, but it doesn't on my production server.
Is there a setting im missing?? how could i fix this?? i have the exact same problem with all the tables of my database and i wouldn't want to modify all the statements in my program... if it's possible
Thank you in advance!!
I found it!!! or remembered it... a while ago i heard something about "STRICT MODE", and i suddenly remembered about it!! so i looked for how to turn off the "strict mode" and i found two methods:
Method 1:
Open the "my.ini" file within the MySQL installation directory and look for something like...
# Set the SQL mode to strict
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Replace with:
# Set the SQL mode to strict
sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
Method 2:
You may be able to run an SQL query within your database management tool such as phpMyAdmin which can normally be found from your web hosting control panel:
SET ##global.sql_mode= '';
I Think the first method is permanent, and the second one has to be done every connection... i think

Why am I getting a table doesn't exist error for a table that exists?

I am running a simple update statement:
UPDATE sometab
SET `somefield1` = '19',
`somefield2` = '3734941'
WHERE somefield3 = '1234';
and I am getting the error:
ERROR 1146 (42S02): Table 'prod._sometab_new' doesn't exist
I can successfully select from the table where somefield3 is 1234.
Why am I getting a table doesn't exist error for a table that exists? And why does the error message refer to a different table? I don't see any triggers associated with the table.
Additional information: A colleague just noticed that it is referring to a prod scheme, but the statement is running in a dev schema built from prod. The update statement works in DBs that were built a few days ago using the same method, but all of the DBs built after some, as of yet, unknown time exhibit the error.
The current theory is that a conversion script to move us to UTF-8 is currently running and creating tables like _ORIG_new as part of its conversion. We are going to wait for the conversion script to finish and then rebuild the dev databases and see if the error still persists.
Does this happen if you also try Insert into or Delete statements ?
Insert INTO sometab(somefield1, somefield2) VALUES (a, b).
If that works you should not have problems probably, otherwise you have problems accessing your database.
Second, are you sure you are using the correct database file and that are you connected to it properly. If you are using it in external application (c#), check your connection strings.
Also check how are you executing the query. I cant think of other more specific solution to your problem

Logging query errors in MySQL

We have an application that uses several SQL queries and might at times generate the odd error.
For example, it could be a :
INSERT INTO TABLE (ID, FIELD) VALUES (1, "field value");
which would result in a:
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
Because the unique primary key constraint has been violated.
Is it possible in MySQL to somehow log the error along with the query that caused it? I have tried to enable the error-log and general-log in the /etc/mysql/my.cnf but it never produced the expected result. I could enable logging of every query without their errors (pretty useless for us, we're only interested in queries that result in errors).
The errors can be caught by the applications (in our case they are, we are using Perl DBI), however when there are several statements in a stored procedure then we do not know which one as the error message does not include the text of the query, or even the name of the table involved. This makes troubleshooting quite difficult.
I am sure I am missing something obvious. For example, in Oracle this is the default behavior, query errors are logged into a text file where they can be easily identified.
This is a client thing. Isolate database accesses in an access layer and generate the log on the client. The database cannot log this.