How to insert duplicate rows in SQLite with a unique ID? - sql

This seems simple enough: I want to duplicate a row in a SQLite table:
INSERT INTO table SELECT * FROM table WHERE rowId=5;
If there were no explicit unique column declarations, the statement would work, but the table's first column is declared rowID INTEGER NOT NULL PRIMARY KEY. Is there any way to create a simple statement like the one above that works without knowing the schema of the table (aside from the first column)?

This can be done using * syntax without having to know the schema of the table (other than the name of the primary key). The trick is to create a temporary table using the "CREATE TABLE AS" syntax.
In this example I assume that there is an existing, populated, table called "src" with an INTEGER PRIMARY KEY called "id", as well as several other columns. To duplicate the rows of "src", use the following SQL in SQLite3:
CREATE TEMPORARY TABLE tmp AS SELECT * FROM src;
UPDATE tmp SET id = NULL;
INSERT INTO src SELECT * FROM tmp;
DROP TABLE tmp;
The above example duplicates all rows of the table "src". To only duplicate a desired row, simply add a WHERE clause to the first line. This example works because the table "tmp" has no primary key constraint, but "src" does. Inserting NULL primary keys into src causes them to be given auto-generated values.
From the sqlite documentation: http://www.sqlite.org/lang_createtable.html
A "CREATE TABLE ... AS SELECT" statement creates and populates a database table based on the results of a SELECT statement. A table created using CREATE TABLE AS has no PRIMARY KEY and no constraints of any kind.
If you want to get really fancy, you can add a trigger that updates a third table which maps old primary keys to newly generated primary keys.

No. You need to know the schema of the table to write the insert statement properly.
You need to be able to write the statement in the form of:
insert into Table (column1, column2, column3)
select column1, column2, column3
from OtherTable
where rowId = 5

Well, since I was unable to do this the way I wanted, I resorted to using the implicit row id, which handily enough has the same name as the rowId column I defined explicitly, so now I can use the query I had in the question, and it will insert all the data with a new rowId. To keep the rest of the program working, I just changed SELECT * FROM table to SELECT rowId,* FROM table and everything's fine.

Absolutely no way to do this. Primary Key declaration implies this field is unique. You can't have a non unique PK. There is no way to create a row with existing PK in the same table.

Related

Generate and Insert surrogate keys into already existing BigQuery table

I have an existing table without any unique ID. I'm planning to generate surrogate keys using GENERATE_UUID() statement however I'm sure not how to insert this new column... What is the best option here?
One way is to use CREATE OR REPLACE TABLE ... AS SELECT
CREATE OR REPLACE TABLE table_a
AS SELECT GENERATE_UUID() uuid, * FROM table_a
The drawback is:
The metadata of the table is lost (table options, column descriptions etc.)
Nullability of the columns is lost, all columns becomes NULLABLE
If both are acceptable, then approach above is the simplest way
If not, then you need to add a column through UI or API, then do
UPDATE table_a
SET uuid = GENERATE_UUID()
WHERE uuid IS NULL

How to make a general reference to the primary key column in oracle SQL?

I have multiple tables with a unique column name for each of their primary key such as: DeviceName, DeviceNumber, SwitchNumber, Etc.
There is another table which serves as an audit trail containing the changes from all tables, it lists the table name and the primary key value for each respective table as a reference i.e.
Table#2
TableName, InstanceNumber
I would like to use the information in table #2 to pull the respective records from each table in 'TableName' by referencing the 'InstanceNumber' attribute as the PK for each respective table without having to manually create a reference for each table's column name.
Is there a way I can do this? That is, create a query that references a 'general' column name to a table that points to the primary key column?
Select * from (TableName) where (PrimaryKeyColumn) = (InstanceNumber);
You can only do this using dynamic SQL -- in PL/SQL, that would be execute immediate.
Why not? Here is one reason. All the columns returned by a query need to be known when the query is compiled. That is, before any data is read. You are requesting a set of columns that depends on the table that is in the data. So, the columns are NOT known and the query cannot be compiled.

add a primary key to new table created by query result

I want to create a table using query result. But I want to also add a auto increment primary key field to it. Is it possible to achieve it using SQLite?
Example:
Select two fields from table_a. But I want the output schema as (id, field_a, field_b).
create table foo as
select field_a, field_b
from tablel_a
Currently using SQLite 3, but solutions using other database systems are also fine.
This is not possible with a single statement; CREATE TABLE ... AS ... does not create constraints.
You have to use two statements:
CREATE TABLE foo ( ID INTEGER PRIMARY KEY, [...] );
INSERT INTO foo (...) SELECT ...;
by default sqlite adds a rowid column in every table you create , so unless there's some specific need here, you can use this rowid column
check this out https://www.sqlite.org/lang_createtable.html#rowid

Select row query given table name and primary key in Oracle?

So after googling this simple question, I could have not find an answer anywhere. I only have very basic database knowledge, and I need a query in Oracle to properly select a row given a table name and a primary key. Most examples I have found all find rows based of a row number or rowID (is that the same as primary key?).
Any help on this would be greatly appreciated.
Do you have the primary key column and the value you want to query? Where or what exactly did you search for? This is a very basic SELECT statement in any relational database:
SELECT *
FROM table_name
WHERE primary_key_column = primary_key_value
Unless, of course, I didn't understand the question.
A primary key is a unique identifier for a row in a table. Each row will have a primary key that is different from all other rows. This key can be one value, such as a rowID, or it can be a composite value (multiple columns used as a primary key because there may not be a need for an extra column only to store a rowID).
#tilley31 above shows a great example of how to search for a specific row in a table. If the primary key was composite;
SELECT *
FROM table_name
WHERE primary_key_column1 = primary_key_value1
AND primary_key_column2 = primary_key_value2
ROWID is a pseudocolumn that returns the address of a row and is usually unique, exception being where more than one table is stored in a same cluster then those tables rows can share the same rowid. ROWID is implicitly given by the oracle to rows.
Primary key uniquely identifies a row at a table level and is created by the user who created the table.
Getting the ROWID of a Row
SELECT ROWID,FIELDNAME FROM ABC;
Getting the PRIMARY Key of a table
SELECT * FROM USER_CONSTRAINTS WHERE TABLE_NAME='YOUR_TABLENAME'
AND CONSTRAINT_TYPE='P';
I guess you are intent to dynamically choose table and where clauses in query (?)
If this is what you want to do then answer is No. Its not possible just through query. You could achieve it through pl/sql. and if you must have this as a query consider using a table function like below -
SELECT * FROM TABLE(func('TABLE_NAME','WHERE_CONDITION'))
Check out this link: https://oracle-base.com/articles/misc/pipelined-table-functions
Again this requires you to have preset output columns (COLUMN1, COLUMN2 etc). You will not be able to select exact column names from table.
Overall this is going to be messy.

H2 Database - Reorder columns using SQL

I have a H2 database with 16 million entries and no primary key. I successfully added an auto-incrementing primary key using the following statements:
ALTER TABLE
PUBLIC.ADDRESSES ADD ID BIGINT AUTO_INCREMENT;
ALTER TABLE
PUBLIC.ADDRESSES ADD PRIMARY KEY (ID)
Now the problem is, that the column order is STREET, HOUSENUMBER, ..., ID, but I would like ID to be the first column of the table. It looks like there is a corresponding ALTER TABLE statement MySQL (see here), but I'm unable to adapt it to H2.
Long story short: How can I change the column order to ID, STREET, HOUSENUMBER ...? Is there a solution similar to:
ALTER TABLE "ADDRESSES" MODIFY COLUMN "ID" BEFORE "STREET";
Any help is kindly appreciated.
H2 does not currently support re-ordering columns. You would need to run multiple statements:
First, rename the column, then add a new column with the right name at the right position (alter table add supports positioning), and finally drop the old column.
Or, probably more elegant, use rename table and then create table ... as select.