update&select in on transaction ,can't get the data - mysql

background:
sprintboot + mysql5.7 + mybatis
repeatable read
i thought i can select the data which insert in one transcation.but the answer is no.
#Transactionnal
public void test(){
dao.insert();//insert data
dao.select();//select data insert previous row.but can't find
}
i tried command in mysql client, like this :
start transaction;
insert into ....
select * from ....
commit;
and the data insert can be found in select after insert;
i really can't understand why .

Related

I want to prevent specific value insert into ulog2_ct table

I'm using ulog2 with mysql for gathering nf_conntrack values to DB in my bridge machine.
All things are works well, but I want to prevent to insert specific value which has "right(hex(orig_ip_saddr),8)='7f000001'".
I just execute query as "delete from ulog2_ct where right(hex(orig_ip_saddr),8)='7f000001' " periodically but its not good solution.
ulog2 provide queries to make and insert into the specific DB as https://github.com/inliniac/ulogd2/blob/master/doc/mysql-ulogd2-flat.sql
But I can't fully understand because I'm not sql expert.
I think some additional query would resolve what I want but I don't know how.
Insert query of mysql-ulogd2-flat.sql is as below: (line 435)
BEGIN
INSERT INTO ulog2_ct (oob_family, orig_ip_saddr, orig_ip_daddr, orig_ip_protocol,
orig_l4_sport, orig_l4_dport, orig_bytes, orig_packets,
reply_ip_saddr, reply_ip_daddr, reply_ip_protocol,
reply_l4_sport, reply_l4_dport, reply_bytes, reply_packets,
icmp_code, icmp_type, ct_mark,
flow_start_sec, flow_start_usec,
flow_end_sec, flow_end_usec)
VALUES (_oob_family, _orig_ip_saddr, _orig_ip_daddr, _orig_ip_protocol,
_orig_l4_sport, _orig_l4_dport, _orig_bytes, _orig_packets,
_reply_ip_saddr, _reply_ip_daddr, _reply_ip_protocol,
_reply_l4_sport, _reply_l4_dport, _reply_bytes, _reply_packets,
_icmp_code, _icmp_type, _ct_mark,
_flow_start_sec, _flow_start_usec,
_flow_end_sec, _flow_end_usec);
RETURN LAST_INSERT_ID();
END
Seo.
Just create a trigger on ulog2_ct
(check for syntax validation , as I have just typed it here)
CREATE TRIGGER trig_ulog2_ct
BEFORE INSERT ON ulog2_ct
FOR EACH ROW
BEGIN
DECLARE msg VARCHAR(255);
IF (right(hex(new.orig_ip_saddr),8)='7f000001') THEN
SIGNAL 'your error message Not to insert'
END IF;
END
Let us know

Submitting multiple query transactions in CFscript

I am having trouble finding the correct syntax to execute multiple MySQL statements at once, like with cftransaction. I'm trying to implement this in a CFC in pure cfscript.
<cftransaction>
DROP TABLE IF EXISTS SOME_TEMP_TBL;
CREATE TABLE SOME_TEMP_TBL AS
(
SELECT * FROM ANOTHER_TBL
);
DROP TABLE IF EXISTS SOME_TEMP_TBL_2;
CREATE TABLE SOME_TEMP_TBL_2 AS
(
SELECT * FROM ANOTHER_TBL_2
);
</cftransaction>
So I have the SQL statements chained together as a string:
var SQL = "
DROP TABLE IF EXISTS SOME_TEMP_TBL;
CREATE TABLE SOME_TEMP_TBL AS
(
SELECT * FROM ANOTHER_TBL
);
DROP TABLE IF EXISTS SOME_TEMP_TBL_2;
CREATE TABLE SOME_TEMP_TBL_2 AS
(
SELECT * FROM ANOTHER_TBL_2
);
";
And if I understand right I think I need to use a transaction {} block. But do I put raw MySQL code in there? Currently I'm trying to attach it to a Query object but Base.cfc (Railo) is throwing an error saying the datasource isn't defined.
transaction
{
qTrans = new Query();
qTrans.setSQL(SQL);
qTrans.execute();
qTrans.setDatasource(variables.instance.datasource.getDSN());
if (good)
{
transaction action="commit";
} else {
transaction action="rollback";
}
}
Have also tried just SQL.execute() but of course execute() isn't defined for a string & it wouldn't relate to any DB anyway...
Also, is the if(good) portion required? By default does if(good) test for whether or not a MySQL error occurred? And is transaction action="commit" what actually sends the SQL script?
Do I need to split these up into separate Query objects and run them sequentially? And if so what's the point of even having the transaction block in CFscript?
I know I'm way off here but I'm having a hard time navigating the CF documentation around this. If anyone knows of a good source specifically for CFscript references I could really use one, because I struggle with Adobe's version.
Try this code
try {
transaction {
qTrans = new Query();
qTrans.setDatasource(variables.instance.datasource.getDSN());
qTrans.setSQL(SQL);
qryRes = qTrans.execute();
TransactionCommit();
}
} catch(database e) {
TransactionRollback();
}

Sqljocky, transactioned query with multiple sets of parameters

I'm using sqljocky to insert data into a MySQL database. I need to truncate a table first, then insert multiple rows in it. I would do this in a single transaction, but it seems that sqljocky doesn't support this at all now (or maybe I'm quite new in dart and sqljocky).
The solution I found is the following, but I was wondering if there's a better one.
// Start transaction
pool.query('START TRANSACTION').then((r) {
// Truncate table
pool.query('TRUNCATE myTable').then((r) {
// Prepare statement to insert new data
pool.prepare('REPLACE INTO myTable (Id, Name, Description) VALUES (?,?,?)').then((query) {
// Execute query inserting multiple rows
query.executeMulti(myArrayValues).then((results) {
// Other stuff here
pool.query('COMMIT').then((r) {
...
To be honest, I'm still wondering if this code really executes a transactioned query!
Here's the same code rewritten with transaction support:
// Start transaction
pool.startTransaction().then((trans) {
// Delete all from table
trans.query('DELETE FROM myTable WHERE 1=1').then((r) {
// Prepare statement
trans.prepare('REPLACE INTO myTable (Id, Name, Description) VALUES (?,?,?)').then((query) {
// Execute query inserting multiple rows
query.executeMulti(myArrayValues).then((results) {
// Stuff here
// Commit
trans.commit().then((r) { ...
Use ConectionPool.startTransaction().
* You
* must use this method rather than `query('start transaction')` otherwise
* subsequent queries may get executed on other connections which are not
* in the transaction.
Haven't tried it myself yet.

Qt's odbc driver does not support LastInsertId with mysql, whats the workaround?

Im using Qt 4.8.3 and the MySQL ODBC 3.51 Driver. The driver does not seem to support LastInsertId which I test like this:
db.driver()->hasFeature(QSqlDriver::LastInsertId)
I need it to find the auto increment id I just inserted
query.exec("INSERT INTO myTable (MyVal, Created) VALUES ('1', NOW())");
auto insertId = query.lastInsertId().toString();
What is the best workaround?
EDIT: there will be concurrent access to this table from multiple clients.
According to MySQL documentation, you can call:
SELECT LAST_INSERT_ID();
after the insert query to get the latest id inserted for the current connection, even when using ODBC.
You could do something like:
query.exec("SELECT id FROM myTable ORDER BY id DESC LIMIT 1");
to get the largest id in your table - this should be the one you just inserted.
If you are writing an application that can have multiple concurrent users you'll have to look into creating a lock on your table and then releasing the lock after you run this second query.
Use OUTPUT INSERTED.[Field Name] as in code below.
Read the returned ID with next() function.
bool RepeatsRecognizer::InsertEvent(RepEvent* event){
QSqlDatabase db = AppManager::DB_Output()->ThreadDatabase();
QSqlQuery query(db);
query.prepare("INSERT INTO RepEvents (ChannelID, StatsRangeUID, MinStartDateTime, MaxDuration, Fixed) OUTPUT INSERTED.ID"
" VALUES (?, ?, ?, ?, ?)");
query.bindValue(0, event->ChannelID);
query.bindValue(1, event->StatsRangeUID.toString());
query.bindValue(2, event->MinStartDateTime);
query.bindValue(3, event->MaxDuration);
query.bindValue(4, false);
if (!query.exec())
return false;
if (!query.next())
return false;
event->ID = query.value(0).toLongLong();
qDebug() << __FUNCTION__ << "Event ID:" << event->ID;
}

Inserting a JSON Object into a database

I am building a DataSnap server in Delphi XE2, and I'm having trouble figuring out the best way to insert the JSON Object that the client sends me into a Database.
Here's the format of the object I'm receiving:
{"PK":0,"FIELD1":"EXAMPLE","FIELD2":5, "DATE":""}
The solution I found was the following code
with qryDBMethods do
begin
SQL.Text := 'SELECT * FROM Table';
Open;
Append;
FieldByName('PK') .AsInteger := StrToInt(newId.ToString)
FieldByName('FIELD1').AsString := Object.Get('FIELD1').JsonValue.Value;
FieldByName('FIELD2').AsInteger := StrToInt(Object.Get('FIELD2').JsonValue.Value);
FieldByName('DATE') .AsDateTime:= Now;
Post;
After that, I would have my query component made into a JSON Object and returned to my client, but problem is, this is going to be a big application with dense tables and so doing a "SELECT * " every time I want to insert something isn't ideal. What is the best way to do this?
Try using a INSERT sentence instead.
with qryDBMethods do
begin
SQL.Text := 'INSERT INTO Table (PK, FIELD1, FIELD2) VALUES (:PK, :FIELD1, :FIELD2)';
ParamByName('PK') .Value:= StrToInt(newId.ToString)
ParamByName('FIELD1').Value := Object.Get('FIELD1').JsonValue.Value;
ParamByName('FIELD2').Value:= StrToInt(Object.Get('FIELD2').JsonValue.Value);
ExecSQL();
If what the problem is the amount of data when you open a Select * From Table, why not do something like Select * From Table Where 1 <> 1?
This way you would be able to insert while not loading any result.
Other option would to make an Insert script instead.