Conditional put, update in dynamodb - .net-core

I have one table with 4 col A, B, C, Username and want to hit conditional update such that if in a request while updating it, should check only if any of the A, B, c col value is changed then only update the Username col. If all other col value is same as existing one then Username should not be updated.

Related

How to prevent the deadlock in the below situation?

I have a table, which should hold rows for OrderGroups. Basically, when a client creates an Order, his Order should be put inside a group based on his client id, until an administrator can verify the order. The OrderGroups tables structure is the following:
OrderGroupId | IsClosed | clientId
-------------------------------------------------
INT PRIMARY (AutoIncrement) | BOOLEAN | INT
My code should work in the following way: when a client creates a new order, we should check if he already has a NOT cloesd order group. If he has, we should attach that order group to his order. If he has none, we should create a new order group for him, and attach his order to the newly created group.
In the past, no locking was used when fetching/creating the order group, which resulted in naturally, that some clients, when inserting multiple orders concurently, ended up with multiple open order groups. I've modified my order group fetching query, to the following:
BEGIN TRANSACTION;
SELECT * FROM OrderGroups WHERE clientId = {id} AND IsClosed = 0 FOR UPDATE;
// if no order groups are returned, insert a new group and use that one
// if an order group is returned, use the returned order group
END TRANSACTION;
This prevents the appeareance of multiple OrderGroups, but it sometimes results in a deadlock. I presume that the reason for this, is how MariaDB is locking the rows, when they are not present. Basically, if a result would be returned by the query in question, all subsequent calls requesting the same row, should wait, until the transaction that was first requesting it for update, commits or rolls back. But this is not the case, if a non-existent row gets locked this way. The insersions are still prevented (that is why I am getting the deadlock), but the select queries are processed.
Basically, this is what happens:
C1 -> BEGIN TRANSACTION;
C1 -> SELECT OrderGroups WHERE clientId = 1 AND IsClosed = 0 FOR UPDATE; // returns no rows
C2 -> BEGIN TRANSACTION;
C2 -> SELECT OrderGroups WHERE clientId = 1 AND IsClosed = 0 FOR UPDATE; // returns no rows, instead of waiting for C1 to commit or rollback the transaction
C1 -> INSERT INTO OrderGroups SET clientId = 1, IsClosed = 0; // holds, because C2 has a for update lock on the row? being inserted
C2 -> INSERT INTO OrderGroups SET clientId = 1, IsClosed = 0; // holds, because C1 has a for update lock on the row
MARIADB -> randomly kills C1 or C2 because of the deadlock, while the other may finish
How could I avoid this deadlock situation, and still maintain the single open group policy for the OrderGroups table?
For the moment, I managed to resolve this in a kind of hackish way, by inserting a new, unique column inside the table.
I've inserted the UniqId (VARCHAR(20)) column as a unique in the database. When I am trying to fetch or create a new row in the table, instead of selecting and then inserting if nothing is found, I just simply make an INSERT IGNORE INTO ... using c{clientId} for the UniqId column. Whenever the order group is closed, I update the UniqId column to the primary key of the table.
This way, when performing the INSERT IGNORE, if the row already exists, it gets locked, and I will be able to select it inside the next SELECT statement, and if the row does not exist yet, it gets inserted and also gets locked, and I am able to select it in the next select statement.
This is a rather hacky way to solve my exact situation, but I am still open to suggestions for the possibility, to somehow get an exclusive lock for a row in the table, that does not exist yet.

Selecting a random record in SQLite from records that have a specific value to a column

I am making an application in Android, and I am using SQLite database.
Is it possible for me to select a random record in a table from the records that have a specific value to one of the columns?
Let’s say I have a table called T, which has a set of columns: a, b, c.
Can I select a random record from this table, but ONLY from the records with no null value for the “c” column?
Not sure if you mean columns when you say attributes. If so, do you mean something like this:
SELECT * FROM T WHERE c IS NOT NULL ORDER BY RANDOM() LIMIT 1;
Yes it is possible, you could use something like :-
SELECT * FROM t WHERE c IS NOT NULL ORDER BY random() LIMIT 1;
This utilises the random function to ORDER the result set using the ORDER BY clause and then selects just 1 row via the LIMIT clause.
P.S. a, b and c are generally called columns rather than attributes

Use 1:n DeleteActions

How is it possible to use DeleteActions for 1:n table-relations?
Example:
Table A ("id")
('foo')
,('bar')
,('blup')
Table B: ("id", "tableAId1", "tableAId2")
(1, 'foo', 'blup')
,(2, 'bar', 'foo')
I have two relations on tableB:
TableB:tableAId1 -> TableA:id
TableB:tableAId2 -> TableA:id
Both datasets in table B should be deleted, if 'foo' from table A is deleted.
I tried one delete-Action on table A, refering to table B with cascade-option, resulting in only dataset 1 in table B was deleted.
I tried two identical delete-Action on table A, refering to table B with cascade-option, resulting in table lock on database.
I know about overwriting delete() method on table A, but this isn't safe if using tableA.doDelete().
In AX 2009 and previous a delete action on a table only follows one of the relations (the first alphabetically sorted). A table should only be applied as a delete action once.
Your best choice then is to do your own cascade delete using delete_from in the delete method of your master table. If you do a doDelete, it will not delete the child records. Then just don't use the doDelete method!
In AX 2012 you explicitly specify which relation to follow on a delete action. You can apply the same table more than once, provided you specify different relations.
This is a nice feature, but is one of the reasons that table relations on the extended data types had to die.

Insert or ignore every column

I have a problem with a sqlite command.
I have a table with three columns: Id, user, number.
The id is continuing. Now if I put a user and a number inside my list, my app should compare if such a user with this number already exist. The problem is, if I use a standard "insert or ignore" command, the Id column is not fixed, so I will get a new entry every time.
So is it possible just two compare two of three columns if they are equal?
Or do I have to use a temporary list, where are only two columns exist?
The INSERT OR IGNORE statement ignores the new record if it would violate a UNIQUE constraint.
Such a constraint is created implicitly for the PRIMARY KEY, but you can also create one explicitly for any other columns:
CREATE TABLE MyTable (
ID integer PRIMARY KEY,
User text,
Number number,
UNIQUE (User, Number)
);
You shouldn't use insert or ignore unless you are specifying the key, which you aren't and in my opinion never should if your key is an Identity (Auto number).
Based on User and Number making a record in your table unique, you don't need the id column and your primary key should be user,number.
If for some reason you don't want to do that, and bearing in mind in that case you are saying that User,Number is not your uniqueness constraint then something like
if not exists(Select 1 From MyTable Where user = 10 and Number = 15)
Insert MyTable(user,number) Values(10,15)
would do the job. Not a SqlLite boy, so you might have to rwiddle with the syntax and wrap escape your column names.

How to make Oracle Query recognizable to ASP.NET table adapter?

I have a query with a sub query in the select that needs to get a value from a certain table if it exists. I don't want to paste the query here for business reasons, but here's a simplified example of what I am trying to do:
select a, b, (select x from z) as c from table where ...
The query runs fine in TOAD, but when I go through the ASP.NET table adapter wizard in my data object, it complains about the sql statement: "Error in SELECT clause NEAR ','". I'm not sure if it would still work at runtime even though it complains? I know the preview doesn't work and it didn't create the data table. Anyone experienced this?
The reason I want to do it this way is because the query that populates field c will not always have a value but I have to return a and b even if c does not have a value. Any one good with knowledge of sql may be able to suggest a work around. I want to stick with 1 table adapter query if possible.
Outer join to table Z?
SELECT t.a,t.b,z.x
FROM table t LEFT OUTER JOIN Z ON (t.y = Z.y)
WHERE...
This will give you the values from Z if they exist, NULL otherwise.
When a tool doesn't understand a query, one method that always works is to create a view that encapsulates your query.
CREATE VIEW v AS SELECT a, b, (select x from z) as c from table
You would then use a simple query in ASP.NET like :
SELECT a, b, c FROM v where...
The view now contains your business logic and would be kept in your source control repository alongside all your other code.

Resources