Add primary key to an existing table - sql

How to add a primary key to an existing table in SQLite? I know that I have to generate a new table and copy everything from the old table. However, it keeps giving me an error saying datatype mismatch due to one table having a primary key and the other one not. I did run the same commands without including primary key and it works.
CREATE TABLE temp_table
(
id INTEGER PRIMARY KEY,
age INTEGER,
address TEXT
)
INSERT INTO temp_table
SELECT *
FROM original_table
Since I am importing the data from a CSV file I do not know how to add the PRIMARY KEY in the first place. In case anyone knows a solution for that it would also work.

Assuming that the original table has 2 columns: age and address, you can either list the column names of the new table without the primary key:
INSERT INTO temp_table(age, address)
SELECT age, address FROM original_table
or, include the primary key and pass null for its value:
INSERT INTO temp_table(id, age, address)
SELECT null, age, address FROM original_table
or:
INSERT INTO temp_table
SELECT null, age, address FROM original_table
In all cases the id will be filled by SQLite, because it is defined as INTEGER PRIMARY KEY and it will be automatically autoincremented starting from 1.
If there is another column in the original table with unique integer values, you can pass that column to fill the new id:
INSERT INTO temp_table(id, age, address)
SELECT col, age, address FROM original_table
Change col to the actual name of the column.

Related

I need to write a sp that will insert the characters after the first 4000 characters on the second line

I have a column named 'Products' and its VARCHAR2(4000). In some cases I send more characters than 4000. It looks like '1,2,3,4,5,6...'. How can i insert first 4000 characters into one row and insert remaining to another row but of course it should consider the comma.
I tried to use array system but couldnt figure it out.
Don't use comma-demilited strings.
If you are going to store relational data then use another table.
If you are currently using:
CREATE TABLE main_table (
id NUMBER
GENERATED ALWAYS AS IDENTITY
PRIMARY KEY,
product_ids VARCHAR2(4000)
);
Then change it to:
CREATE TABLE main_table (
id NUMBER
GENERATED ALWAYS AS IDENTITY
PRIMARY KEY
);
CREATE TABLE main_table_products (
id REFERENCES main_table (id),
product_id NUMBER
-- Assuming you have a products table
REFERENCES products (id),
CONSTRAINT main_table_products__pk PRIMARY KEY (id, product_id)
);
Then you know:
The product_ids are all the correct data type,
You have referential constraints insuring that the product_ids are valid products.
You do not have duplicate product_ids for each id as the primary key prevents it.
You can insert any number of product_ids.
You can easily delete or update product_ids.
If you use a delimited VARCHAR2 string then you do not (out-of-the-box) have any of those benefits.

Using column name as part of foreign key relationship

As part of the application I am building I want to store the values of all dropdowns in a single table, where all table/column combinations that represent a dropdown will be able to reference it.
Something like the below:
CREATE TABLE dropdown_def
(
id int,
table_id int,
field_name TEXT,
value TEXT,
PRIMARY KEY (id),
UNIQUE (table_id, field_name, value)
);
INSERT INTO test1.dropdowns (id, table_id, field_name, value)
VALUES (1, 1, 'status', 'active');
CREATE TABLE clients
(
id int,
table_id int,
status TEXT,
FOREIGN KEY (table_id, 'status', status)
REFERENCES dropdowns (table_id, field_name, value)
);
I tried the above but with no surprise it seems you cannot use the actual column name as part of the foreign key constraint.
Is there any other way of using the column identifier in a FK?
You can have a constant stored computed column for the FK.
CREATE TABLE clients
(
id int,
table_id int,
status TEXT,
refcolname text GENERATED ALWAYS AS ('status') STORED,
FOREIGN KEY (table_id, refcolname, status)
REFERENCES dropdowns (table_id, field_name, value)
);
Really I would advice against the design like that. Why to create a united table of lookups just to get troubles referencing its parts. Use the EAV pattern only if it is absolutely inevitable, for example a set of lookup tables is to be defined by a user at runtime.

Primary key without duplicated values

i'm trying and success to create primary key in Redshif
create table my_table(id int ,
primary key(id));
insert into my_table values
(id),
(1),
(1),
(20);
select count(*) from my_table
3
but it allows me to upload duplicated value ,
as far as i know primary key should contain unique values ,
did i do something wrong?
you can find your answer here
How to create an Index in Amazon Redshift
one of the answers mention your problem with the primary key
Create an identity key which will act as an auto_increment surrogate key. This'll serve both the purpose - to uniquely identify the records in the table and prevent insertion of duplicate values.
Let's create a dummy table:
create table scratchpad.test_1
(id bigint identity(1,1),
name varchar(10));
insert into scratchpad.test_1(name)
values
('a'),('b'),('c'),('d');
select * from scratchpad.test_1;
The id column acts as a primary key. Deleting any record from the table does not impact the sequencing of other values and the id column can be used to uniquely identify the subsequent row.

Auto generate ID in massive PostgreSQL INSERT

I try to copy a table into another, but the fields are not the same (it is not a problem), and some fields in table destination are optional.
I do somethink like this:
INSERT INTO data(Email, Title, FirstName, LastName)
SELECT champs5, champs1, champs3, champs4
FROM tmp
But the problem comes from the id field who is of course required:
ERROR: null value in column "id" violates not-null constraint
How can I tell to Postgres to auto generate the ID for each line of the INSERT?

Why can't you use SQLite ROWID as a Primary key?

This does not execute:
create table TestTable (name text, age integer, primary key (ROWID))
The error message is:
11-23 11:05:05.298: ERROR/Database(31335): Failure 1 (table TestTable has no column named ROWID) on 0x2ab378 when preparing 'create table TestTable (name text, age integer, primary key (ROWID))'.
However, after the TestTable is created, this prepares and executes just fine:
create table TestTable (name text, age integer);
insert into TestTable (name, age) values ('Styler', 27);
select * from TestTable where ROWID=1;
I could potentially see ROWID as being a solution to needing an auto-increment primary key and foreign key which are never going to be used as populated as data on the application layer. Since ROWID is hidden from select result sets by default, it would have been nice to associate this with the primary key while keeping it hidden from the application logic. OracleBlog: ROWNUM and ROWID say this is impossible and inadvisable, but doesn't provide much explanation other than that.
So, since the answer to 'is this possible' is definitely no/inadvisable, the question is more or less 'why not'?
Summary from SQLite.org:
In SQLite, table rows normally have a 64-bit signed integer ROWID
which is unique among all rows in the same table. (WITHOUT ROWID
tables are the exception.)
If a table contains a column of type INTEGER PRIMARY KEY, then that
column becomes an alias for the ROWID. You can then access the ROWID
using any of four different names, the original three names (ROWID,
_ROWID_, or OID) or the name given to the INTEGER PRIMARY KEY
column. All these names are aliases for one another and work equally
well in any context.
Just use it as the primary key.