mysql update updating all user rows in table - mysql

Problem:
I have a mySql stored procedure which runs the following UPDATE:
IF target = 'sup' THEN
UPDATE my_table SET deleted = 1, last_updated = lastUpdate WHERE id = ID AND user_id = accountID;
END IF;
The input parameters are:
(IN ID BIGINT, IN lastUpdate DATETIME, IN target VARCHAR(3), IN accountID BIGINT)
When this sproc is called, mySql updates all of the rows in the table for the user_id and seems to ignore the id in the WHERE clause.
Background:
A mobile app makes an ajax json call to a .NET webservice, which then calls the mySql sproc.
The json call is like:
{"id":["5","6","10"],"lastUpdated":"2014-07-19 22:28:53","target":"sup","accountID":"309"}
At the .net webservice, it converts each id entry to Int64 and sends it to the mySql sproc:
For Each checkedID As String In id
cmd.Parameters.AddWithValue("#ID", CType(checkedID, Int64)).Direction = ParameterDirection.Input
cmd.Parameters.AddWithValue("#lastUpdate", dte).Direction = ParameterDirection.Input
cmd.Parameters.AddWithValue("#target", target).Direction = ParameterDirection.Input
cmd.Parameters.AddWithValue("#accountID", accountID).Direction = ParameterDirection.Input
cmd.ExecuteNonQuery()
cmd.Parameters.Clear()
Next
Research and fix attempts:
Lots of search
Using MySQL Workbench; running the SQL directly correctly updates just the targeted row:
UPDATE my_table SET deleted = 1, last_updated = '1970-01-01 10:10:10' WHERE id = "7" AND user_id = 309;
However, if I call the sproc from within MySQL Workbench, it still updates all of the rows for the targeted user:
CALL `my_sproc`(7, '1990-01-01 10:10:10', 'sup', 309);
I cannot see anything wrong with the sproc, unless I've just looked at it for too long. The mobile app has got close to 100 MySQL sprocs, and this is the only one causing an issue.
I am stumped.

Just adding an explicit reference to the table fixed the issue.
my_table.id

Related

generate queries for each key in pyspark data frame

I have a data frame in pyspark like below
df = spark.createDataFrame(
[
('2021-10-01','A',25),
('2021-10-02','B',24),
('2021-10-03','C',20),
('2021-10-04','D',21),
('2021-10-05','E',20),
('2021-10-06','F',22),
('2021-10-07','G',23),
('2021-10-08','H',24)],("RUN_DATE", "NAME", "VALUE"))
Now using this data frame I want to update a table in MySql
# query to run should be similar to this
update_query = "UPDATE DB.TABLE SET DATE = '2021-10-01', VALUE = 25 WHERE NAME = 'A'"
# mysql_conn is a function which I use to connect to `MySql` from `pyspark` and run queries
# Invoking the function
mysql_conn(host, user_name, password, update_query)
Now when I invoke the mysql_conn function by passing parameters the query runs successfully and the record gets updated in the MySql table.
Now I want to run the update statement for all the records in the data frame.
For each NAME it has to pick the RUN_DATE and VALUE and replace in update_query and trigger the mysql_conn.
I think we need to a for loop but not sure how to proceed.
Instead of iterating through the dataframe with a for loop, it would be better to distribute the workload across each partitions using foreachPartition. Moreover, since you are writing a custom query instead of executing one query for each query, it would be more efficient to execute a batch operation to reduce the round trips, latency and concurrent connections. Eg
def update_db(rows):
temp_table_query=""
for row in rows:
if len(temp_table_query) > 0:
temp_table_query = temp_table_query + " UNION ALL "
temp_table_query = temp_table_query + " SELECT '%s' as RUNDATE, '%s' as NAME, %d as VALUE " % (row.RUN_DATE,row.NAME,row.VALUE)
update_query="""
UPDATE DBTABLE
INNER JOIN (
%s
) new_records ON DBTABLE.NAME = new_records.NAME
SET
DBTABLE.DATE = new_records.RUNDATE,
DBTABLE.VALUE = new_records.VALUE
""" % (temp_table_query)
mysql_conn(host, user_name, password, update_query)
df.foreachPartition(update_db)
View Demo on how the UPDATE query works
Let me know if this works for you.

Hibernate query for employee with date

This is my code.. Query working when i search with mysql query(find it in screenshot).But failed with hiberbate query.
EmployeeAttendanceMaster masterEmployeeFromRepository = masterEmployeeRepository.findById(employee, date);
if (masterEmployeeFromRepository == null) {
System.out.println("SignIn Successfully");
}else System.out.println("You are already Logged In");
masterEmployeeRepository:
#Query("select me from EmployeeAttendanceMaster me where me.employee = ?1 and Date(me.date) = ?2 order by me.date desc")
EmployeeAttendanceMaster findById(Employee employee,Date date);
mysql db screenshot in with same query
Data with same date there in db..So it shoudnot go through if condition.It should follow else condition.But as long as i tried this it prints "SignIn Successfully"
Thanks advance
You are using the Spring Data JPA #Query annotation (as discerned from the full data type you have provided in the comments to your question). The query you specify with #Query (select me from EmployeeAttendanceMaster me ...) must be a valid JPA Query Language (JPQL) statement. From what I know and remember, JPQL does not have a Date() function. So, your query is invalid because it contains Date(me.date) which refers to a non-existent JPQL Date() function, even if you can run it directly on MySQL.
You can change your query declaration to:
#Query(value = "select * from EmployeeAttendanceMaster where employee_id = ?1 and Date(date) = ?2 order by date desc", nativeQuery = true)
This will force the JPA provider (Hibernate in your case) to treat the query as a native SQL query and will be executed on the underlying database without any translation. You will lose database independence though.

"Row cannot be located for updating" error [another]

I'm working with Delphi (XE3) and need to connect to a MySQL database. I'm having a strange problem that seems quite common but I still haven't entirely solved this problem.
traditional solutions include:
setting "Update Criteria" to adCriteriaKey.
ensure your table has a primary key (and tell the ADO Table about it)
problem 1:
start the application, execute the code: if the new value happens to match what's already in the database, I get the error at position "B".
problem 2:
start the application, execute the code: if the new value happens to be different from what's already in the database, it will execute successfully once and thereafter, give an error at position "A".
there shouldn't be any problem locating the record at anytime since the record primary key has not been changed.
object conMain: TADOConnection
Connected = True
ConnectionString =
'Provider=MSDASQL.1;Password=p;Persist Security Info=True;U' +
'ser ID=M;Extended Properties="Driver={MySQL ODBC 5.3 ANSI Dri' +
'ver};SERVER=yukon;DATABASE=db;UID=M;Pwd=p;PORT=3306;' +
'"'
LoginPrompt = False
Mode = cmShareDenyNone
Left = 48
Top = 24
end
object ADOTable1: TADOTable
Connection = conMain
IndexFieldNames = 'FacilityID'
TableName = 'facility'
Left = 152
Top = 24
end
procedure TForm1.Button1Click(Sender: TObject);
begin
conMain.Open;
ADOTable1.Open;
ADOTable1.Properties.Item['Update Criteria'].Value:=adCriteriaKey;
// **A**
if ADOTable1.Locate('facilityid', '{C0FADCC8-15C9-48C8-8003-3BBD4AB74586}', []) then
begin
ADOTable1.Edit;
ADOTable1.FieldByName('facilityaddress1').AsString:='mickey street';
ADOTable1.Properties.Item['Update Criteria'].Value:=adCriteriaKey;
// **B**
ADOTable1.Post;
end
else
showmessage('not found!');
ADOTable1.Close;
conMain.Close;
end;
it's as though the Post method or the connection left the database in some intermediate state...
here's what the database log says when I demonstrate problem 1.
M#D3400 on db
SET NAMES latin1
SET character_set_results = NULL
SET SQL_AUTO_IS_NULL = 0
select database()
select database()
SHOW GLOBAL STATUS
SELECT ##tx_isolation
set ##sql_select_limit=DEFAULT
select * from facility
SHOW KEYS FROM `facility`
UPDATE `db`.`facility` SET `FacilityAddress1`=? WHERE `facilityid`=?
UPDATE `db`.`facility` SET `FacilityAddress1`='mickey street22' WHERE `facilityid`='{C0FADCC8-15C9-48C8-8003-3BBD4AB74586}'
here's what the database log says when I demonstrate problem 2.
SHOW GLOBAL STATUS
M#D3400 on db
SET NAMES latin1
SET character_set_results = NULL
SET SQL_AUTO_IS_NULL = 0
select database()
select database()
SELECT ##tx_isolation
set ##sql_select_limit=DEFAULT
select * from facility
SHOW KEYS FROM `facility`
UPDATE `db`.`facility` SET `FacilityAddress1`=? WHERE `facilityid`=?
// SUCCESSFUL
UPDATE `db`.`facility` SET `FacilityAddress1`='mickey street22' WHERE `facilityid`='{C0FADCC8-15C9-48C8-8003-3BBD4AB74586}'
SHOW GLOBAL STATUS
SHOW GLOBAL STATUS
SHOW GLOBAL STATUS
db
select * from facility
UPDATE `db`.`facility` SET `FacilityAddress1`=? WHERE `facilityid`=?
// ERROR!
UPDATE `db`.`facility` SET `FacilityAddress1`='mickey street22' WHERE `facilityid`='{C0FADCC8-15C9-48C8-8003-3BBD4AB74586}'
SHOW GLOBAL STATUS
setting the "Update Criteria" in various places was of no help.
reduced the table down to just two fields: facilityid varchar(38), facilityaddress1 varchar(50). same result...
form http://www.connectionstrings.com/mysql-connector-odbc-5-2/, I found:
Provider=MSDASQL;Driver={MySQL ODBC 5.3 UNICODE Driver};Persist Security Info=True;Server=yukon;Database=ocean;User=M;Password=p;Option=2;
"Option=2" is suggested for VB
http://dev.mysql.com/doc/connector-odbc/en/connector-odbc-configuration-connection-parameters.html#codbc-dsn-option-combos
works!
Thank you all for your contributions.

MySql AES-Decrypted Field empty

I was trying to en- and decypt data with the corresponding MySQL-functions.
This is what I did:
INSERT INTO dbsec.tbl_credent (U_Password) VALUES (AES_ENCRYPT('secretText', SHA2('pwd123',512)));
the Primary-Key (id) was 6. So I used
SELECT dbsec.tbl_credent.U_Password FROM dbsec.tbl_credent WHERE dbsec.tbl_credent.id = '6';
I got something like this:
Ž4•ý/2Ÿ½üyÙ¤Ý'
So encryption seems to work so far.
When I start the following query:
SELECT AES_DECRYPT(dbsec.tbl_credent.U_Password, 'pwd123') FROM dbsec.tbl_credent WHERE dbsec.tbl_credent.id = '6';
Result is NULL
I used hashing for the password so I tried
SELECT AES_DECRYPT(dbsec.tbl_credent.U_Password, SHA2('pwd123',512)) FROM dbsec.tbl_credent WHERE dbsec.tbl_credent.id = '6';
Result is 73656372657454657874
As all this didn't work I tested this directly:
SELECT AES_DECRYPT(AES_ENCRYPT('secretText', SHA2('pwd123',512)), 'pwd123');
Again the Result was NULL and
SELECT AES_DECRYPT(AES_ENCRYPT('secretText', 'pwd123'), 'pwd123');
returned 73656372657454657874 again.
What do I have to do to get back the 'secretText' I have encrypted?
The Type of U_Password is text (latin1_swedish_ci), btw.

Executing an update statement with a select subquery clause in C

I have the following sql that I run in C:
snprintf(sql, 200, "update rec set name = (select name from pers where id = %d )
where id = %d",rec_id , emp_id );
mysql_query(conn, sql) returns a successful result but it's putting 1 in the "rec" table in the "name" field instead of the name, but when I printf the output and use it in MySQL it's working fine.
update rec set name = (select name from pers where id = 104 ) where id = 43
Is there something wrong with my sprintf? Or something has to be added?
I also tried static sql command like this
snprintf(sql,"update rec set name = (select name from pers where id = 104 ) where id = 43");
and it also put 1 in the rec.name
Is that due to count of record returned by the sub query? Can you verify by putting a condition which returns e.g. 2 records so that the name is set to 2? if this is the reason then (though less performing approach) try splitting the queries and see if it works this time.