SQLite starting rowid of 0 - python-2.7

I'm trying to set up a SQLite table where the rowid starts from 0 instead of the default 1. The end goal is to be able to run the first INSERT statement and have it insert to rowid 0. Explicitly setting rowid to 0 for that first INSERT is not an option.
I've tried a few things related to AUTOINCREMENT but am not having any luck getting this to work cleanly. The only successful way I've found is to insert a row with rowid of -1 and then delete it later. This works but it's messy and I'd like to find a cleaner way of doing it. I am working in Python 2.7 with the built-in sqlite3 library.
The bottom-line question:
Is there a cleaner way to start rowid from 0 other than manually inserting a -1 value and then removing it later?
Some side information:
I found a similar question here and played with some AUTOINCREMENT settings: Set start value for AUTOINCREMENT in SQLite
The sqlite_sequence table doesn't seem to work with negative numbers. I used the following to test it:
import sqlite3
con = sqlite3.Connection('db.db')
cur = con.cursor()
cur.execute("CREATE TABLE test(id INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)")
cur.execute("INSERT INTO sqlite_sequence (name,seq) VALUES (?,?)", ('test',-1))
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 1
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 2
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 3
cur.execute("SELECT rowid, id, val FROM test")
print cur.fetchall()
With the -1 inserted into sqlite_sequence it should set the next rowid to 0, but it's using 1 instead. If sqlite_sequence is initialized to a positive number the rowids are as expected.
import sqlite3
con = sqlite3.Connection('db.db')
cur = con.cursor()
cur.execute("CREATE TABLE test(id INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)")
cur.execute("INSERT INTO sqlite_sequence (name,seq) VALUES (?,?)", ('test',10))
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 11
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 12
cur.execute("INSERT INTO test (val) VALUES (?)", ('testval',)) #becomes rowid 13
cur.execute("SELECT rowid, id, val FROM test")
print cur.fetchall()
Does auto-increment not support negative numbers like this? I couldn't find any mention of it in the SQLite documentation.

The documentation says that, with AUTOINCREMENT,
the ROWID chosen for the new row is at least one larger than the largest ROWID that has ever before existed in that same table.
So the algorithm looks not only at the value in the sqlite_sequence table, but also at the last row in the table, and uses the larger of these two values.
When the table is empty, the largest actual rowid is instead assumed to be zero. This is done so that the first inserted rowid becomes 1.
Therefore, the only way to generate a rowid less than one is to have another row already in the table.

I was using sqlite in java and unintentionally go the first row to have ROWID=0.
Here is the code
long dbid = getDbid();
ContentValues values = new ContentValues();
values.put(KEY_ROWID, dbId); // Line that cause ROWID == 0 when dbid == 0
values.put(KEY_KEY, key);
values.put(KEY_VALUE, value);
if (dbId == 0) {
dbId = dbase.insert(PREFERENCES_TABLE, null, values);
map_.put(key, new Pair<>(dbId, value));
}
else
dbase.update(PREFERENCES_TABLE, values, KEY_ROWID + "=" + dbId, null);
The intent was to have zero be an uninitialized value but insert was returning zero. I didn't want the first ROWID to equal zero so I removed the line and insert returned one.

Related

In Presto how to query a cloumn which no value

I have a integer column which is empty. How to query that I tried
select * from table where target_status_code = null
but it did not return anything
Probably you should use is null to check the integer column which is empty:
select * from table where target_status_code is null

Auto increment item (ordinal numbers) in Oracle APEX

I want to make my item id auto increment, so that user cannot insert any number. It is for ordinal numbers of inovice items, so there can't be any gaps.
Table:
TABLE_NAME (id NUMBER GENERATED ALWAYS AS IDENTITY( NOCACHE), name VARCHAR2(10), PRIMARY KEY (id));
Then I created a process with PL/SQL code:
IF :P27_ID IS NULL THEN
SELECT ID.NEXTVAL INTO :P27_ID FROM DUAL;
END IF;
But if I delete an item, his value is lost and next entered item won't have his id.

SQLite increment Integer Primary Key and Unique Constraint conflict

I have a SQLite database.
When writing move rows function, which moves rows from one table to another I need to have a query for incrementing column with name "row" which is INTEGER PRIMARY KEY, but there is an error. It is critical to have indexing with row in my task. The condition in example is WHERE row >= 2 because i am inserting rows from other table into position 2.
"UPDATE '4' SET row = row + 1 WHERE row >= 2"
Error("19", "Unable to fetch row", "UNIQUE constraint failed: 4.row")
The problem's origin WHERE row >= 2" part. How to overcome this problem?
The problem's origin WHERE row >= 2" part.
I'm inclined to disagree. The problem is not with which rows are updated, it is with the order in which they are updated.
Very likely SQLite will process rows in rowid order, which almost certainly is also increasing order of the row column, since that column is an auto-incremented PK. Suppose, then, that the table contains two rows with row values 2 and 3. If it processes the first row first, then it attempts to set that row's row value to 3, but that produces a constraint violation because that column is subject to a uniqueness constraint, and there is already a row with value 3 in that column.
How to overcome this problem?
Do not modify PK values, and especially do not modify the values of surrogate PKs, which substantially all auto-increment keys are.
Alternatively, update the rows into a temporary table, clear the original table, and copy the updated values back into it. This can be extremely messy if you have any FKs referencing this PK, however, so go back to the "Do not modify PK values" advice that I led off with.
First: '4' is not a table name. The UPDATE statement expects a table name where you have written '4'. For example:
UPDATE table1 SET row = row + 1 WHERE row >= 2
Second: Just do not use row as a primary key (or unique key, for that matter) when it obviously is not meant as primary key but as a changing row number. Create a separate column that can be used as primary index of that table instead.

sql Column with multiple values (query implementation in a cpp file )

I am using this link.
I have connected my cpp file with Eclipse to my Database with 3 tables (two simple tables
Person and Item
and a third one PersonItem that connects them). In the third table I use one simple primary and then two foreign keys like that:
CREATE TABLE PersonsItems(PersonsItemsId int not null auto_increment primary key,
Person_Id int not null,
Item_id int not null,
constraint fk_Person_id foreign key (Person_Id) references Person(PersonId),
constraint fk_Item_id foreign key (Item_id) references Items(ItemId));
So, then with embedded sql in c I want a Person to have multiple items.
My code:
mysql_query(connection, \
"INSERT INTO PersonsItems(PersonsItemsId, Person_Id, Item_id) VALUES (1,1,5), (1,1,8);");
printf("%ld PersonsItems Row(s) Updated!\n", (long) mysql_affected_rows(connection));
//SELECT newly inserted record.
mysql_query(connection, \
"SELECT Order_id FROM PersonsItems");
//Resource struct with rows of returned data.
resource = mysql_use_result(connection);
// Fetch multiple results
while((result = mysql_fetch_row(resource))) {
printf("%s %s\n",result[0], result[1]);
}
My result is
-1 PersonsItems Row(s) Updated!
5
but with VALUES (1,1,5), (1,1,8);
I would like that to be
-1 PersonsItems Row(s) Updated!
5 8
Can somone tell me why is this not happening?
Kind regards.
I suspect this is because your first insert is failing with the following error:
Duplicate entry '1' for key 'PRIMARY'
Because you are trying to insert 1 twice into the PersonsItemsId which is the primary key so has to be unique (it is also auto_increment so there is no need to specify a value at all);
This is why rows affected is -1, and why in this line:
printf("%s %s\n",result[0], result[1]);
you are only seeing 5 because the first statement failed after the values (1,1,5) had already been inserted, so there is still one row of data in the table.
I think to get the behaviour you are expecting you need to use the ON DUPLICATE KEY UPDATE syntax:
INSERT INTO PersonsItems(PersonsItemsId, Person_Id, order_id)
VALUES (1,1,5), (1,1,8)
ON DUPLICATE KEY UPDATE Person_id = VALUES(person_Id), Order_ID = VALUES(Order_ID);
Example on SQL Fiddle
Or do not specify the value for personsItemsID and let auto_increment do its thing:
INSERT INTO PersonsItems( Person_Id, order_id)
VALUES (1,5), (1,8);
Example on SQL Fiddle
I think you have a typo or mistake in your two queries.
You are inserting "PersonsItemsId, Person_Id, Item_id"
INSERT INTO PersonsItems(PersonsItemsId, Person_Id, Item_id) VALUES (1,1,5), (1,1,8)
and then your select statement selects "Order_id".
SELECT Order_id FROM PersonsItems
In order to achieve 5, 8 as you request, your second query needs to be:
SELECT Item_id FROM PersonsItems
Edit to add:
Your primary key is autoincrement so you don't need to pass it to your insert statement (in fact it will error as you pass 1 twice).
You only need to insert your other columns:
INSERT INTO PersonsItems(Person_Id, Item_id) VALUES (1,5), (1,8)

Remove rows from SQL DB that appear in a Array

I Develop with MFC Visual C++ and Oracle SQL Server.
I have SQL table with: IDs, value and time, when the application insert a new row: some ID, some Value and time being inserted.
My goal is to delete rows of values that were changed between certain time. since the data that was inserted during that time has incorrect value.
Where is the catch ? I dont need to delete all the rows that were updated in that time period, only the rows with IDs that appear on a certain CArray.
I can go through each ID from CArray and execute a delete query to that certain ID in that time period (whether there is entry or not) - problem since i can have 150K IDs to iterate
on..
Thanks
DELETE FROM table-name WHERE id in (...)
transform your array into a tempTable with one column and then delete from your destiantion table where ID in (select Id from temptable)
Here is an example:
declare #RegionID varchar(50)
SET #RegionID = '853,834,16,467,841'
declare #S varchar(20)
if LEN(#RegionID) > 0 SET #RegionID = #RegionID + ','
CREATE TABLE #ARRAY(region_ID VARCHAR(20))
WHILE LEN(#RegionID) > 0 BEGIN
SELECT #S = LTRIM(SUBSTRING(#RegionID, 1, CHARINDEX(',', #RegionID) - 1))
INSERT INTO #ARRAY (region_ID) VALUES (#S)
SELECT #RegionID = SUBSTRING(#RegionID, CHARINDEX(',', #RegionID) + 1, LEN(#RegionID))
END
delete from from your_table
where regionID IN (select region_ID from #ARRAY)