H2 Database - Reorder columns using SQL - 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.

Related

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.

Altering my primary key to auto increment - JavaDB

I am using Netbeans, writing in Java and using Derby.
I have a table within APP called PERSON. Within PERSON I have a column called PID with the following properties:
Name: PID
Nulls allowed: [ ]
Data type: NUMERIC
Column size: 4
Decimal digits: 0
Position: 1
Part of a primary key: [/]
Part of an index: [/]
I used the meta data isAutoIncrement function to check if it was already auto incrementing and it is not!
I have since tried using the following SQL commands to alter it:
I believe this may not have been for Derby:
ALTER TABLE APP.PERSON ALTER PID NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY
(START WITH 1, INCREMENT BY 1);
Upon checking the Oracle website, I found the correct syntax:
ALTER TABLE APP.PERSON ALTER PID SET INCREMENT BY 1;
I even tried leading zeros:
ALTER TABLE APP.PERSON ALTER PID SET INCREMENT BY 0001;
None of which have worked, the error I get on the last two are:
ALTER TABLE '"APP"."PERSON"' specified attributes for column 'PID' that are
not compatible with the existing column.
Any ideas of the correct syntax?
Here's what I generally do to accomplish this:
Create a new table, with the desired schema, including the generated primary key
Issue a INSERT INTO newtable SELECT columns FROM oldtable to populate the new table's data from the old table
Rename the old table to some temporary name, like table_soon_to_be_deleted
Rename the new table to the desired table name
Do some testing to make sure that my behavior is as expected
Drop the old table that I renamed in step (4).
JavaDB does not allow altering a column with generated key word so I found the best way is to recreate the table and specify the primary key as auto incremented. For example;
create table staff(
ID int primary key always generated as identity,
name varchar(100)
);
This worked for me.

How to alter column from PRIMARY KEY to IDENTITY for Derby

The SQL for the creation of the table is:
CREATE TABLE myTable(id INTEGER NOT NULL PRIMARY KEY, ...)
Instead I need it to be:
CREATE TABLE myTable(id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), ...)
as described in the Derby documentation. So my question is what would be the alter statement I would need to create AFTER the initial create statement? In other words:
CREATE TABLE myTable(id INTEGER NOT NULL PRIMARY KEY, ...)
ALTER TABLE myTable ...
Thank you very much for the assistance!
Looking at the documentation this seems impossible. You can change the type length (not even the type itself), the default, nullability and the next generated value but even the last option requires the column to already be defined as IDENTITY. A thread from 2009 says that you can't even add an IDENTITY column. A test confirms this is true to this day.
So it seems there is only one solution: You have to replace the table. Something like this:
create a new table with a placeholder name that contains the desired columns
copy any data over from the original table
drop the original table
rename the new table
It's really an unfortunate solution because if you already have other tables referencing the id column of your table as that would mean further work.
I tried messing with the system tables but they seem to be read-only (and for good reason).
Looks like this issue in Derby has been fixed as of the 10.12.1.1 release. Now commands such as:
ALTER TABLE t ADD COLUMN x INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY
to an existing database now work, as does GENERATED BY DEFAULT. Looks like the change requires the underlying database to be at least in 10.11 format.
One technique is to: (a) create a new table with the new column defined as you desire, and all other columns as they were before, (b) run an INSERT INTO ... SELECT ... statement to copy all the data from the existing table to the new table, (c) RENAME TABLE to rename the old table to some other name, (d) RENAME TABLE to rename the new table to the correct tablename, and then finally (e) DROP TABLE the old table.

SQL: Create new column with default, unique value

I have added a new column, called Ordinal, to a table called Activity. The problem is that I gave it a UNIQUE constraint, set it to allow NULL (though this I won't want in the end.. I just needed to set it to that to get a little farther with the script), and did not give it a default value. I'm now running a RedGate SQL Compare script that was generated by comparing this table to a version of the Activity table that does not have the column. But I'm getting the following error:
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'iwt.Activity' and the index name 'IX_Activity'. The duplicate key value is (1).
So based on my research, it's trying to create a unique key constraint on the Ordinal column, but NULL is not unique. So my next step was to give it a unique value of 1 just to let the script pass. But 1 isn't going to be unique either. So, finally, my question:
Preferably in SQL Server Management Studio, how do I set a column as having a unique default value? Isn't that what I would need to create this constraint?
Thanks.
try this:
NULL will be the first constraint when you create the column.
UNIQUE will be as add constraint, you should add the second constraint.
they can run on this order with no problem (tested):
--first constraint
alter table Table_Name
add Column_Name int null
--second constraint
alter table Table_Name
add constraint Constraint_Name unique (Column_Name)
In my example :
PaymentGatewayHash is column
Cart is a table
--first query
alter table Cart
add PaymentGatewayHash NVARCHAR(20) null
--second query
CREATE UNIQUE INDEX PaymentGatewayHashUnique
ON Cart (PaymentGatewayHash)
WHERE PaymentGatewayHash IS NOT NULL
I just tested that :D

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

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.