Can I add values with conditions in mySQL [duplicate] - mysql

This question already has answers here:
MySQL You are using safe update mode and you tried to update a table without a WHERE
(2 answers)
Closed 2 years ago.
I'm trying to add a numeric value to a column whose "AuthDate" is "06/05/20" and "Time" is "1P -2P".
I ran the following query:
update main
set calls = 2072
where authdate = '06/05/20'
and time = '1P - 2P';
*main = table name
calls = column name
but I get error code 1175 You are using safe update mode
Does anyone know why I get the error?

Your database or session has option sql_safe_updates enabled. Amongst other things, this forbids update that do not have a where clause, or that have a where clause whose columns are not keys (are not indexed). Even if there is an index, but the optimize chooses not to use it, the query is also aborted.
This is more of an option that prevents mistakes from beginners. If you really know what you are doing, you can disable the option at session level:
set sql_safe_updates = 0;
Side note: I am suspicious about condition authdate = '06/05/20':
if autdate is of a date-like datatype, then you should give it a legitimate date string, like: authdate = '2020-06-05' (or '2020-05-06'?)
if it's a string then... consider storing it as a date; storing dates as string is bad practice for many reasons, and should be avoided

Related

In MySQL, can I get the column type and and check column values in a single SELECT statement?

I'll start this off by saying I know that there are more practical ways to solve this. It's more of an intellectual curiosity than anything else.
I've inherited a MySQL database where some columns are stored as varchar(5) but actually contain the literals "True" or "False". Changing the structure of the data is not an option right now due to other issues. I'm mapping the columns to an ORM (SQLAlchemy), and I want the column to be mapped to a Boolean data type in the supporting codebase using a type adapter. (I've written this adapter already; it's not the problem.)
To help make the mapping process faster, I'm writing a small query to look at the INFORMATION_SCHEMA table and build a line of Python code defining the column using the ORM's syntax. I cannot assume that the data type varchar(5) is a Boolean column - I need to inspect the contents of that column to see if there are values contained in it besides True and False.
Can I write a query that will both get the column type from INFORMATION_SCHEMA and check the actual values stored in that column?
Here is the query I have so far:
SELECT CONCAT(
"Column(""",
col.column_name,
""", ",
(CASE
WHEN col.DATA_TYPE = "int" THEN "Integer"
-- Code in question
WHEN
col.DATA_TYPE = "varchar"
AND col.CHARACTER_MAXIMUM_LENGTH = 5
AND NOT EXISTS(
-- Doesn't seem to work
SELECT DISTINCT col.COLUMN_NAME
FROM col.TABLE_NAME
WHERE col.COLUMN_NAME NOT IN ("True", "False")
)
THEN "BoolStoredAsVarchar"
WHEN col.DATA_TYPE = "varchar" THEN CONCAT("String(", col.CHARACTER_MAXIMUM_LENGTH, ")")
-- Default if it's not a recognized column type
ELSE col.DATA_TYPE
END),
"),"
) AS alchemy
FROM information_schema.columns AS col
WHERE
col.TABLE_SCHEMA = "my_schema"
AND col.TABLE_NAME = "my_table"
ORDER BY col.ORDINAL_POSITION;
Running this code gives me a permissions error: Error Code: 1142. SELECT command denied to user 'user'#'host' for table 'table_name'. Presumably it's trying to use col.TABLE_NAME as a literal instead of interpreting it.
I've also tried creating a simple stored procedure and making table_name into a variable. However, replacing the FROM clause inside the EXISTS with a variable name gives me a syntax error instead.
Again, it's easy enough to run the query myself to see what's in that column. I'd just like to know if this is possible, and if so, how to do it.
You can't do what you're trying to do in a single query.
The reason is that table names (or any other identifier) must be fixed in the query at the time it is parsed, which is before it has read any values from tables. Thus you can't read the name of a table as a string from information_schema and also read from the table with that name in the same query.
You must read the table name from information_schema and then use that result to format a second query.
This isn't a problem specific to MySQL. It's true of any SQL implementation.

Issues when getting ID from DB [duplicate]

This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
Closed 2 years ago.
I hope you all have a good day.
Actually I'm deploying a query to get a complete array of data. But the fact is that I need an Id, first of all, I guess, I must get the last Id first, then I can apply a mathematic operation to get its value + 1. The fact is that I've been trying different sentences and queries with no result.
This is my code:
function obtener_Id(){
global $mysqli;
$resultado_oId = $mysqli ->query("SELECT TOP 1 'id' FROM 'pacient' ORDER BY RowID DESC ")
$id_sacada = mysqli_fetch_assoc($resultado_oId);
$id_enLaMano = $id_sacada['id'];
return $id_enLaMano;
//$id_dinamica = $id_enLaMano + 1;
//return $id_dinamica;
}
As you can see guys, I've commented on the last two lines, cause I´m looking to get at least a value (The result from a query) But Idk if that is correct. Looking on the Internet I've seen relative posts which are solved just to apply the query that we can view under global declarations...
I've tried that on phpMyAdmin with no results and a bunch of errors...
You guys know the correct way to get the max value in the Id column? Or even if I'm doing badly correct me.
A lot of hugs and Luck!
Mizar ^^
I would suggest putting the serial number in a table. Read the serial no before insert, (lock the table, if required) insert the data, then increase the serial no by 1 and update the serial no table with increased value.

How to avoid MySQL Workbench error code: 1175 during this UPDATE *without* disabling "safe updates"

I have a particular MySQL UPDATE statement which does specify the required primary key in its WHERE clause and yet which still produces Error 1175 when run in MySQL Workbench.
I am perfectly aware of MySQL error code: 1175 during UPDATE in MySQL Workbench. My case appears to be the same as MySQL error code: 1175 during UPDATE (MySQL-Workbench vs. console). Like that questioner, I do not wish to disable MySQL-Workbench's "safe update/delete" option. That question failed to get a solution. I would like to try to get an actual solution.
SQL UPDATE statement:
-- update new columns' values from corresponding rows in `charges_arc`
UPDATE `charges`
INNER JOIN `charges_arc` ON `charges`.`ChargeID` = `charges_arc`.`ChargeID`
SET `charges`.`ChargeClearDate` = `charges_arc`.`ChargeClearDate`
WHERE `charges`.`ChargeID` = `charges_arc`.`ChargeID`;
ChargeID is indeed the Primary Key column in both charges and charges_arc tables.
This means that this statement does satisfy MySQL Workbench's https://dev.mysql.com/doc/workbench/en/workbench-faq.html#faq-workbench-delete-safe:
By default, Workbench is configured to not execute DELETE or UPDATE
queries that do not include a WHERE clause on a KEY column.
Is there a solution to rewrite this query such that Workbench does not Error 1175, and which does not require setting SET SQL_SAFE_UPDATES=0/changing Workbench's preferences?
Well, having played further, so far I have found that the following seems to keep Workbench happy:
-- update new columns' values from corresponding rows in `charges_arc`
UPDATE `charges`
INNER JOIN `charges_arc` ON `charges`.`ChargeID` = `charges_arc`.`ChargeID`
SET `charges`.`ChargeClearDate` = `charges_arc`.`ChargeClearDate`
WHERE `charges`.`ChargeID` = `charges_arc`.`ChargeID`
AND `charges`.`ChargeID` <> -9999
That's just adding AND charges.ChargeID <> -9999 to the condition. It hardly narrows the scope much(!), and it's pretty ugly(!). I can only guess that Workbench would like to "see some kind of literal test against the PK", so that you show it you have thought about the PK in a certain way! It does at least allow you to do the query without disabling "safe updates".
I will leave this open for a couple of days to see if someone can think of something neater.
For my own part, I have a lot of these kind of UPDATEs in a large upgrading script file, this looks so ugly to me that I may end up going for SET SQL_SAFE_UPDATES=0 over the whole file after all...
EDIT: In the end I decided it was so ugly having to add something like the extra AND clause above to these types of UPDATE ... JOIN ...s that I preferred to SET SQL_SAFE_UPDATES=0 around them, at least for clarity.
Using MySQL 5.6 and MySQLWorkbench 8, I received this error in the same circumstances. I was able to fix the error by qualifying the field name in the WHERE clause.
For example, this caused the 1175 error:
UPDATE `tReports`
SET
`Title` = Title,
`Descr` = Descr
WHERE `ID` = ID;
And this resolved it:
UPDATE `tReports`
SET
`Title` = Title,
`Descr` = Descr
WHERE `tReports`.`ID` = ID;

ASP Classic recordset unable to see columns with 'table.column_name' format after MySQL conversion

I am currently in the process of converting a large amount of ASP classic/VBscript pages from an old database (Unify Dataserver) to MySQL.
Say you have a query like this:
sql = "SELECT c.container_type, c_amount, c_sdate, c_edate, csrt " & _
"FROM containers c, container_chars cc"
objRS.Open sql, objConn, 3, 1
If I want to reference the column "c_edate", I can simply use this and it works fine:
x = objRS("c_edate")
However, when it comes to referencing a column like "c.container_type" (With a . used to differentiate it from another table, like so:
x = objRS("c.container_type")
It will say
ADODB.Recordset error '800a0cc1'
Item cannot be found in the collection corresponding to the requested name or ordinal.
I can fix it by using a number instead:
objRS(0)
This was never an issue until we switched to MySQL. In our old database, using the rs(table.column_name) format worked just fine. But in MySQL, once you add a (.) to the code, it can't find that item unless you switch it to a number.
As you can imagine, this is quite a pain as I go through the 700+ pages of this website manually counting the placement of each column in the corresponding select statement every time something from the query is referenced.
Does anyone know why this is happening or how to make the rs(table.column_name) format work with MySQL like it does with our old database?
In SQL Server, and apparently in MySQL too, the way to reference a field in the result set is to just use the name, without the prefix.
x = objRS("container_type")
The prefix is needed by the database to differentiate between identically-named columns, but once you send the results to a recordset, that recordset doesn't know or care where the columns came from.
The same goes for aliases:
SQL = "SELECT c.container_type AS ctype, [...]"
...
x = objRS("ctype")
Combining these two facts, if you do have identically-named columns in the result set, you must alias at least one of them. If you don't, it won't necessarily give an error, but you will not be able to reference the second column using the rs("name") syntax.
SQL = "SELECT c1.container_type, c2.container_type AS c_type2, ..."
...
x = objRS("container_type")
y = objRS("c_type2")
[Note that while you're at it, you probably should also modify your FROM clauses to use proper FROM table1 INNER JOIN table2 ON table1.fieldA = table2.fieldB type syntax. The FROM table1, table2 WHERE table1.fieldA = table2.fieldB syntax has been deprecated for many years now.]

Could this simple T-SQL update fail when running on multiple processors?

Assuming that all values of MBR_DTH_DT evaluate to a Date data type other than the value '00000000', could the following UPDATE SQL fail when running on multiple processors if the CAST were performed before the filter by racing threads?
UPDATE a
SET a.[MBR_DTH_DT] = cast(a.[MBR_DTH_DT] as date)
FROM [IPDP_MEMBER_DEMOGRAPHIC_DECBR] a
WHERE a.[MBR_DTH_DT] <> '00000000'
I am trying to find the source of the following error
Error: 2014-01-30 04:42:47.67
Code: 0xC002F210
Source: Execute csp_load_ipdp_member_demographic Execute SQL Task
Description: Executing the query "exec dbo.csp_load_ipdp_member_demographic" failed with the following error: "Conversion failed when converting date and/or time from character string.". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly.
End Error
It could be another UPDATE or INSERT query, but the otehrs in question appear to have data that is proeprly typed from what I see,, so I am left onbly with the above.
No, it simply sounds like you have bad data in the MBR_DTH_DT column, which is VARCHAR but should be a date (once you clean out the bad data).
You can identify those rows using:
SELECT MBR_DTH_DT
FROM dbo.IPDP_MEMBER_DEMOGRAPHIC_DECBR
WHERE ISDATE(MBR_DTH_DT) = 0;
Now, you may only get rows that happen to match the where clause you're using to filter (e.g. MBR_DTH_DT = '00000000').
This has nothing to do with multiple processors, race conditions, etc. It's just that SQL Server can try to perform the cast before it applies the filter.
Randy suggests adding an additional clause, but this is not enough, because the CAST can still happen before any/all filters. You usually work around this by something like this (though it makes absolutely no sense in your case, when everything is the same column):
UPDATE dbo.IPDP_MEMBER_DEMOGRAPHIC_DECBR
SET MBR_DTH_DT = CASE
WHEN ISDATE(MBR_DTH_DT) = 1 THEN CAST(MBR_DTH_DT AS DATE)
ELSE MBR_DTH_DT END
WHERE MBR_DTH_DT <> '00000000';
(I'm not sure why in the question you're using UPDATE alias FROM table AS alias syntax; with a single-table update, this only serves to make the syntax more convoluted.)
However, in this case, this does you absolutely no good; since the target column is a string, you're just trying to convert a string to a date and back to a string again.
The real solution: stop using strings to store dates, and stop using token strings like '00000000' to denote that a date isn't available. Either use a dimension table for your dates or just live with NULL already.
Not likely. Even with multiple processors, there is no guarantee the query will processed in parallel.
Why not try something like this, assuming you're using SQL Server 2012. Even if you're not, you could write a UDF to validate a date like this.
UPDATE a
SET a.[MBR_DTH_DT] = cast(a.[MBR_DTH_DT] as date)
FROM [IPDP_MEMBER_DEMOGRAPHIC_DECBR] a
WHERE a.[MBR_DTH_DT] <> '00000000' And IsDate(MBR_DTH_DT) = 1
Most likely you have bad data are are not aware of it.
Whoops, just checked. IsDate has been available since SQL 2005. So try using it.