Delete statement not executed in postgresql - postgresql

I am creating a transaction where I want to update a user in one table and delete some data in another that belongs to that user. But only the first query is executed, not the second one. In the delete statement in the second query code is a comma-separated std::string.
pqxx::connection c(connectionString);
try {
pqxx::work w(c);
pqxx::result r;
c.prepare("user", "update user set started = null, finished = null, task = $1 where id = $2");
r = w.prepared("user")(task)(email).exec();
c.prepare("belongings", "delete from belongings where id in " \
"(select id from info where code in ($1) and id = $2)");
r = w.prepared("belongings")(code)(id).exec();
w.commit();
}
I read this SO-thread that explain how to run multiple queries before commit(). So I must be making a mistake in the second delete statement but can't find the reason.

The code parameter is interpreted as a single literal. You can try to use the alternative syntax of any(array expression), e.g.:
code = "{abc,def}"; // instead of code = "'abc','def'"
...
c.prepare("belongings", "delete from belongings where id in " \
"(select id from info where code = any ($1) and id = $2)");
r = w.prepared("belongings")(code)(id).exec();

Related

QSqlQuery Postgres multiple select

I have a query which contains two part. First part call function which creates a temporary table, second part select data from this table.
SELECT create_data_slice(15962, NULL, ARRAY[[15726]]);
SELECT
AK."15962_15726" as AK_NAME
FROM
t15962 AK
GROUP BY
AK."15962_15726;"
If I execute this query in PgAdmin, it turns right result with data. But if I execute it in Qt:
QSqlDatabase db = store->get_db();
QSqlQuery query(db);
query.exec(sql);
it executes only the first part (create temporary table), but do not execute second part and do not return data.
You can use a transaction like this:
QSqlDatabase::database().transaction();
QSqlQuery query;
query.exec("SELECT create_data_slice(15962, NULL, ARRAY[[15726]]);");
if (query.next())
{
int employeeId = query.value(0).toInt();
query.exec("SELECT AK."15962_15726" as AK_NAME FROM t15962 AK GROUP BY AK."15962_15726;");
while(query.next())
{
qDebug() << query.value().toString(); ///or what you want to do with data
}
}
QSqlDatabase::database().commit();

Writing subqueries in orientDB

This is the query i'm using right now :
INSERT INTO details SET name = "INITIALIZE",actionMap ={"1":12:1,"2":12:2};
Here 12:1,12:2 are rid's from another table.I'm facing a lot of problem's hardcoding these rid values.In order to avoid this i'd like to add the query like this
INSERT INTO details SET name = "INITIALIZE",actionMap ={"1":(select #rid from action where start is not null),"2":(select #rid from action where stop is not null)};
I'm getting this exception:
com.orientechnologies.orient.core.exception.OValidationException: The
field 'details.actionMap' has been declared as LINKMAP but the
value is not a record or a record-id
So how can i change my query to help my case.
This indeed can be done in a more gracefull way using batches.
This is just to create the object you want
INSERT INTO details SET name = "INITIALIZE"
We will turn this into
let $inserted = INSERT INTO details SET name = "INITIALIZE"
And add the edges you would like to add:
CREATE EDGE actionMap FROM $inserted TO (SELECT FROM action WHERE start is not null )
CREATE EDGE actionMap FROM $inserted TO (SELECT FROM action WHERE stop is not null )
So the entire batch you would have to run is
let $inserted = INSERT INTO details SET name = "INITIALIZE"
CREATE EDGE actionMap FROM $inserted TO (SELECT FROM action WHERE start is not null )
CREATE EDGE actionMap FROM $inserted TO (SELECT FROM action WHERE stop is not null )
If you have any more questions about this feel free to ask.
Adapted from this question
let $a1 = SELECT FROM action WHERE start IS NOT null
let $a2 = SELECT FROM action WHERE stop IS NOT null
INSERT INTO details SET name = "INITIALIZE", actionMap = {"1": $a1[0], "2": $a2[0]}
This is original answer and is for LINKLIST
Your error states:
The field 'details.actionMap' has been declared as LINKMAP but the value is not a record or a record-id
You are trying to store a value into a field that is supposed to store references
According to orientDB docs
You store references like this:
INSERT INTO Profiles SET name = 'Luca', friends = [#10:3, #10:4]
or with SELECT sub-querie:
INSERT INTO Diver SET name = 'Luca', buddy = (SELECT FROM Diver
WHERE name = 'Marko')
That will make your code to be:
INSERT INTO details SET name = "INITIALIZE", actionMap =[(SELECT FROM action WHERE start IS NOT null),(SELECT FROM action WHERE stop IS NOT null)];
Extra tip:
If you crate your actions in the same time, then you can add details and those 2 action with one query:
INSERT INTO details SET name = "INITIALIZE", actionMap = [(INSERT INTO yourActionTable SET yourActionField = 'yourFirstAction'), (INSERT INTO yourActionTable SET yourActionField = 'YourSecondAction')]

Openerp create function doesn't execute query

Following is my create function for roster module. The problem is that only update query is not working. The query is working fine when it run alone in pgadmin but in here it doesn't. Both Select and Insert queries are working fine.
(I know using cr.execute is not a good practice but I am in little bit hurry with deadlines).
def create(self, cr, uid, values, context=None):
#rec_id=values['id']
sub_day=values['roster_day']
ros_time=values['time_slot']
emp = values['employee']
dept = values['department_id']
sub_emp = values['sub_employee']
#sub_day = datetime.datetime.strptime(sub_day, '%Y-%m-%d')
cr.execute("""SELECT ra.id , ra.emp_id FROM roster_allocation ra, roster_days_allocation rda
WHERE rda.roster_allocation_connection=ra.id and
rda.allocation_start_day='%s' and
rda.roster_time_list=%d and
ra.emp_id=%d"""%(sub_day,ros_time,emp))
exers=cr.fetchone()[0]
cr.execute("""INSERT INTO roster_allocation (write_uid,emp_id,department_id) VALUES(%d,%d,%d)""" %(context['uid'], sub_emp, dept))
print "Employee for substitution record inserted successfully"
cr.execute("""UPDATE roster_days_allocation SET roster_allocation_connection = (SELECT MAX(ra.id) FROM roster_allocation ra, roster_substitution rs
WHERE ra.emp_id=rs.sub_employee)
WHERE allocation_start_day = '%s' AND roster_time_list = %d AND roster_allocation_connection = %d""" %(sub_day, ros_time,exers))
print "Employee for substitution record updated successfully"
return super(roster_substitution, self).create(cr, uid, values, context=context)
I have edited UPDATE query and even though it's not the best practice, it worked.
cr.execute (SELECT MAX(ra.id) FROM roster_allocation ra, roster_substitution rs
WHERE ra.emp_id=rs.sub_employee)
val=cr.fetchone()
cr.execute("""UPDATE roster_days_allocation SET roster_allocation_connection = %d
WHERE allocation_start_day = '%s' AND roster_time_list = %d AND roster_allocation_connection = %d""" %(val,sub_day, ros_time,exers))

How to get table rows from sqlite_master using tbl_name

I am trying to get a table based on the rootpage number/tbl_name and store in a custom TableObject.
I am able to get the table name by the root page number/tbl_name, but I have no idea about getting the row values from that table.
Here is what I have:
SELECT * FROM sqlite_master WHERE name='test1';
or
SELECT * FROM sqlite_master WHERE rootpage=4;
This thing gives me a row which has a table .
Now how can I get the test1 contents ?
The test1 table have two rows in it, called age and name. How can I access those columns ?
At the end I end up using the cursor, so the query will be something like:
cursor=db.rawQuery("SELECT * FROM sqlite_master WHERE rootpage = '" + rootNumber + "'",null);
I can use
cursor.getString(getColumnIndex("name")) //w.r.t sqlite_master
cursor.getString(getColumnIndex("rootpage")) //w.r.t sqlite_master
How can I use the same cursor to get something like:
cursor.getString(getColumnIndex("age")) //w.r.t test1
cursor.getString(getColumnIndex("name")) //w.r.t test1
to get the values from the resulted table.
I would suggest you that once you query sqlite_master table using cursor A, don't use the same cursor A as it contains result of the that query result.
Hence you need to fire another query and store the next result in another cursor B so that you don't lose the data from your first query.
For example, for master table,you do something like :
Cursor cursorA = db.rawQuery("SELECT * FROM sqlite_master WHERE rootpage = '" + rootNumber + "'",null);
cursorA.moveToFirst();
String tableName = cursorA.getString(getColumnIndex("name"));
For further getting result from the table "test1" that you got result from the previous query, you can do something like this :
Cursor cursorB = db.rawQuery("SELECT * FROM '" + tableName + "'",null);
cursorB.moveToFirst();
String name= cursorB.getString(getColumnIndex("name")) ;
int age= cursorB.getString(getColumnIndex("age")) ;
Hence you will get the result that you need further from table "test1".
Hope this helps you :)

UPDATE and JOIN with JPQL

Tutorials and samples about JPQL always deal with SELECT statement and sometimes, simple UPDATE statements. I need to update a table with a join.
I have simplified my env :
KEY
= id
- counter
APPLET
= id
! key_id (1-1)
DEVICE
= id
! applet_id (1-1)
! user_id (1-n)
USER
= id
- login
A device has a unique applet, which has a unique keyset. But an user can own several devices.
I need to reset the counter of every KEY attached to the USER login "x".
I tried some syntax with UPDATE and JOIN, without success. Any clue ?
Thank you.
What did you try and what error did you get? What is your object model?
Perhaps something like,
Update Key k set k.counter = 0 where exists (Select u from User u join u.devices d where u.login = "x" and d.applet.key = k)
See,
http://en.wikibooks.org/wiki/Java_Persistence/JPQL_BNF#Update
You could also select the objects and reset the counter in memory and commit the changes.
JPQL does not support join operations in bulk update operations.
When you edit query, nativeQuery = true, you can join.
Query should be written according to the fields in the database.
#Transactional
#Modifying
#Query(nativeQuery = true,
value = "UPDATE Team t" +
" SET current = :current " +
" FROM " +
" members," +
" account" +
" WHERE " +
" members.members_id = t.members_id " +
" AND members.account_id = :account " +
" AND t.current = :current_true ")
int updateTeam(
#Param("current") String current,
#Param("account") Long account,
#Param("current_true") Integer current_true);