How do I update a value in a row in MySQL using Connector/C++ - c++

I have a simple database and want to update an int value. I initially do a query and get back a ResultSet (sql::ResultSet). For each of the entries in the result set I want to modify a value that is in one particular column of a table, then write it back out to the database/update that entry in that row.
It is not clear to me based on the documentation how to do that. I keep seeing "Insert" statements along with updates - but I don't think that is what I want - I want to keep most of the row of data intact - just update one column.
Can someone point me to some sample code or other clear reference/resource?
EDIT:
Alternatively, is there a way to tell the database to update a particular field (row/col) to increment an int value by some value?
EDIT:
So what is the typical way that people use MySQL from C++? Use the C api or the mysql++? I guess I chose the wrong API...

From a quick scan of the docs it appears Connector/C++ is a partial implementation of the Java JDBC API for C++. I didn't find any reference to updateable result sets so this might not be possible. In Java JDBC the ResultSet interface includes support for updating the current row if the statement was created with ResultSet.CONCUR_UPDATABLE concurrency.
You should investigate whether Connector/C++ supports updateable resultsets.
EDIT: To update a row you will need to use a PreparedStatement containing an SQL UPDATE, and then the statement's executeUpdate() method. With this approach you must identify the record to be update with a WHERE clause. For example
update users set userName='John Doe' where userID=?
Then you would create a PreparedStatement, set the parameter value, and then executeUpdate().

Related

DynamoDB version control using sort keys

Anyone that has implemented versioning using sort keys as stated in https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-sort-keys.html?
Trying to implement this using typescript for building a database with versions of the items. Is there any way of doing this using updateItem or is it a get + put operation needed?
Any sample to get me started or help is much appreciated!
The concept of versioning using sort key involves the creation of a completely new item that uses same Partition Key and different Sort Key.
DynamoDB offers some operations that allow to update values within an object in an atomic way, this use case is perfect for when you have something like a counter or a quantity and you want to decrease/increase it without having to read its value first. - Docs here.
In the case you're trying to achieve, as mentioned, you are essentially creating a new object. DynamoDB, by itself, doesn't have any concept of versioning and what this pattern does is to cleverly leverage the relation between Partition Key and Sort Key and the fact that a PK can have multiple SK associated with it, to correlate multiple rows of the same table.
To answer your question, if your only source of truth (or data store) is DynamoDB, then yes, your client will have to first query the table to know which was the last version of the item being updated and then insert the new version.
In case you are recording this information elsewhere and are using DynamoDB only to store these versions, then no, one put operation will be enough but again, this assumes you can retrieve this info somewhere else.
In terms of samples, the official documentation of the AWS SDK is always a good start, in your case I assume you'll want to use the Javascript one which you can find here.
At a very high level, you'll have to do the following:
Create an AWS.DynamoDB() client.
Execute a query using the dynamodb.query() method and specifying the PK of the item you want to update.
Go through the items (rows) returned from the previous query and find the one with the bigger version number as SK.
Put a new item using the dynamodb.putItem() method passing an item with the incremented version number as SK and same PK.
You can do the technique described by Amazon with a read and then a write, or more accurately, a read and then two writes (since they want to update both v0 and a new v4!). Often, you need the extra read because you want to build the new version v4 based on data you read from v3 (or equivalently, v0) - but in case you don't need that, the read is not necessary, and two writes are enough:
You first do an UpdateItem to v0 which increments the "Latest" attribute, sets whatever attributes you want to set in the new version, and uses the ReturnValues parameter to ask the update operation to return the new "Latest" attribute.
Then you write with PutItem the new row for v4 (where 4 is the "Latest" you just read).
This approach is safe in the sense that if two clients try to create two new versions at the same time, each one will pick a different "Latest", and both will appear on the version histories. However, it is not safe in the sense that if the client dies between step 1 and 2, you'll have a "hole" in the version history. However, I don't think there's any implementation of this technique that doesn't suffer from this problem.
After saying this, I want to reiterate what I said in the first paragraph: In most realistic use cases, the new version would be based on the old version, so your code anyway needs to read the old version first, then decide how to change it - and then write it (twice). You can't avoid the read in these cases. By the way, in this case the first write (to v0) would be a conditional update to verify that you only write the new version if the old version is still the same one ("Latest" is the same one you read during the read) - otherwise you'd be basing your modification on a non-current version. This is an example of optimistic locking.

Update multiple field values matching a condition in InfluxDB

In an InfluxDB measurement, how can the field values of points matching a query be updated? Is this still not easily doable as of v1.6?
As the example in that GitHub ticket suggested, what's the cleanest way of achieving something like this?
UPDATE access_log SET username='something' WHERE mac='xxx'
Anything better than driving it all from the client by updating individual points?
Q: How can the field values of points matching a query be updated? Is this still not easily doable as of v1.4?
A: From the best of my knowledge, there isn't an easy way to accomplish update in version 1.4 yet.
Field value of a point can only be updated by overriding. That is, to overwrite its value you'll need to know the details of your points. These details include its timestamp and series information, which is the measurement it reside and its corresponding tags.
Note: This "update" strategy can only be used for changing the field value but not tag value. To update a tag value you'll need to first DELETE the point data first and rewrite the entire point data with the updated tag and value.
Q: Anything better than driving it all from the client by updating individual points?
A: Influxdb supports multi-point write. So if you can build a filter to pre-select a small dataset of points, modify their field values and then override them in bulk.
Update is possible and would take the format:
INSERT measurement,tag_name=tag_value_no_quotes value_key_1=value_value_1,value_key_2=value_value_2 time
for example where I want to update the line with tag my_box at time 1526988768877018669 on the box measurement:
INSERT box,box_name=my_box item_1='apple',item_2='melon' 1526988768877018669

borland builder c++ oracle question

I have a Borland builder c++ 6 application calling Oracle 10g database. Operating over a LAN. When the application in question makes a simple db select e.g.
select table_name from element_tablenames where element_id = 10023842
the following is recorded as happening in Oracle (from the performance logs)
select table_name
from element_tablenames
where element_id = 10023842
then immediately (and not from C++ source code but perhaps deeper)
select table_name, element_tablenames.ROWID
from element_tablenames
where element_id = 10023842
The select statement is only called once in the TADODbQuery object, yet two queries are being performed - one to parse and the other adds the ROWID for executon.
Over a WAN and many, many queries this is obviously a problem to the user.
Does anyone know why this might be happening, can someone suggest a solution?
Agree with Robert.
The ROWID uniquely identifies a row in a table so that the returned record can be applied back to the database with any changes (or as a DELETE).
Is there a way to identify a particular column (or set of columns) as a primary key so that it can be used to identify a row without using a ROWID.
I don't know exactly where the RowID is coming from, it could be either the TAdoQuery implementation or the Oracle Driver. But I am sure I found the reason.
From the Oracle docs:
If the database table does not contain a primary key, the ROWID must be selected explicitly when populating DataTable.
So I suspect your Table does not have a primary key, either add one or add the rowid.
Either way this will solve the duplicate query problem.
Since you are concerned about performance. In general
Using TAdoQuery you can set the CursorType to optimize different behaviors for performance. This article covers this from a TAdoQuery perspective. MSDN also has an article that covers it from from a general ADO Perspective. Finally the specifications from the Oracle Driver can be useful.
I would recommend setting the Cursor to either as they are the only supported by Oracle
ctStatic - Bi-directional query produced.
ctOpenForwardOnly - Unidirectional query produced, fastest but can't call Prior
You can also play with CursorLocation to see how it effects your speed.

Verify the structure of a database? (SQLite in C++ / Qt)

I was wondering what the "best" way to verify the structure of my database is with SQLite in Qt / C++. I'm using SQLite so there is a file which contains my database, and I want to make sure that, when launching the program, the database is structured the way it should be- i.e., it has X tables each with their own Y columns, appropriately named, etc. Could someone point my in the right direction? Thanks so much!
You can get a list of all the tables in the database with this query:
select tbl_name from sqlite_master;
And then for each table returned, run this query to get column information
pragma table_info(my_table);
For the pragma, each row of the result set will contain: a column index, the column name, the column's type affinity, whether the column may be NULL, and the column's default value.
(I'm assuming here that you know how to run SQL queries against your database in the SQLite C interface.)
If you have QT and thus QtSql at hand, you can also use the QSqlDatabase::tables() (API doc) method to get the tables and QSqlDatabase::record(tablename) to get the field names. It can also give you the primary key(s), but for further details you will have to follow pkh's advice to use the table_info pragma.

WQL SELECT with optional column

I need to make a query like this:
SELECT PNPDeviceID FROM Win32_NetworkAdapter WHERE AdapterTypeId = 0
Trouble is, the AdapterTypeId column isn't always present. In this case, I just want everything, like so:
SELECT PNPDeviceID FROM Win32_NetworkAdapter
My WQL/SQL knowledge is extremely limited. Can anybody tell me how to do this in a single query?
EDIT:
A bit more background seems to be required: I am querying Windows for device information using WMI, which uses an SQL-like syntax. So, in my example, I am querying for network adapters that have an AdapterTypeId of 0.
That column is not always present however, meaning that if I enumerate through the returned values then "AdapterTypeId" is not listed.
EDIT 2:
Changed SQL to WQL; apparantly this is more correct.
I am assuming you mean the underlying schema is unreliable.
This is a highly unconventional situation. I suggest that you resolve the issue that is causing the column to not always be present, because to have the schema changing dynamically underneath your application is potentially (almost certainly) disastrous.
Update:
OK, so WQL lets you query objects with a SQL-like syntax but, unlike SQL, the schema can change underneath your feet. This is a classic example of a leaky abstraction, and I now hate WQL without ever having used it :).
Since the available properties are in flux, I am guessing that WQL provides a way to enumerate the properties for a given adapter. Do this, and choose which query to run depending upon the results.
After some Googling, there is an example here, which shows how to enumerate through the available properties. You can use this to determine if AdapterTypeId exists or not.
SELECT PNPDeviceID FROM Win32_NetworkAdapter WHERE AdapterTypeId = {yourDesire} OR AdapterTypeId IS NULL
I assume that you mean that this field is missing from the table.
Do you know before submitting the query if this field exists?
If yes then just create SQL dynamically, otherwise It think you will get syntax error in case of missing field
This is not an SQL question. SQL does not contemplate records with varying schemas in a single table source. Instead (as you mention) this is a different system using an "SQL-like" syntax. You'll have better luck if you recast the question using the actual product that you're trying to query, and information how that product deals with variable record structures is probably discussed in the documentation.