ERROR: relation "schema.TableName_Id_seq" does not exist - when creating table in a new database - sql

I'm having an issue where I used pgAdmin4's GUI to create a SQL table, and I want to use to generated CREATE TABLE script to create this same table in another database.
When I run the CREATE TABLE script generated by pgAdmin4 in my new database, I get the following error:
ERROR: relation "schema.TableName_Id_seq" does not exist
So, it appears that the issue is with my auto-incrementing id column that I created as type SERIAL.
The CREATE TABLE script as provided by pgAdmin4:
-- Table: myschema.TableName
-- DROP TABLE myschema."TableName";
CREATE TABLE myschema."TableName"
(
"Id" integer NOT NULL DEFAULT nextval('myschema."TableName_Id_seq"'::regclass),
/* Other columns here */
CONSTRAINT "TableName_pkey" PRIMARY KEY ("Id")
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE myschema."TableName"
OWNER to JoshuaSchlichting;
Why can't the CREATE TABLE script be used in another database? The relation "schema.TableName_Id_seq" didn't exist in the original database prior to be creating that table. What's happening that is different?

The DDL script provided by pgAdmin4 is not complete. When the table was created, there was an implicit creation of a sequence because of the SERIAL type being select for the Id column.
You can find this newly create sequence with pgAdmin4. To do this, go to
-> your server
-> your database
-> your schema
-> Sequences
-> Right click TableName_Id_seq
-> choose "Create script"
This reveals the script used to create this sequence. In this instance, the following was revealed:
-- SEQUENCE: myschema.TableName
-- DROP SEQUENCE myschema."TableName";
CREATE SEQUENCE myschema."TableName"
INCREMENT 1
START 1
MINVALUE 1
MAXVALUE 2147483647
CACHE 1;
The use of the CREATE SEQUENCE script can be avoided by changing the line of code used to create the Id column in the CREATE TABLE script. Example below:
original line:
"Id" integer NOT NULL DEFAULT nextval('myschema."TableName_Id_seq"'::regclass),
changed to: "Id" SERIAL NOT NULL,

Related

Modify generated column in Oracle

I have created a database table in Oracle with an auto generated column:
ID NUMBER GENERATED ALWAYS AS IDENTITY(START WITH 1 INCREMENT BY 1)
Now I do not need it to be generated automatically. I tried to write:
ALTER TABLE table_name MODIFY id number;
But it did not work. The database gives an error:
32795.0000 - "cannot insert into a generated always identity column"
Can someone please explain how to solve this issue without dropping the column?
(There's no such thing as "PLSQL database"; PL/SQL is a procedural extension to Oracle's SQL. Database is Oracle.)
Drop the identity:
SQL> create table test
2 (id number generated always as identity (start with 1 increment by 1));
Table created.
SQL> alter table test modify id drop identity;
Table altered.
SQL>

How do I create a postrgresql database using SQL's DDL on pgadmin4?

I'm learning DDL to create and define an SQL database with Postgresql 10.
I have the something like the following SQL code in an .sql file, and I want to input it in psql or PgAdmin 4, just to test the syntax and see the database structure:
CREATE DATABASE database;
CREATE TYPE t_name AS
( first VARCHAR(30),
last VARCHAR(60)
);
CREATE TABLE telephone_m
( tnumber VARCHAR(15) NOT NULL UNIQUE
);
CREATE TABLE people
( curp CHAR(18) NOT NULL PRIMARY KEY,
pname t_name NOT NULL,
birth_date DATE NOT NULL,
telephone_m VARCHAR(15) REFERENCES telephone_m
);
CREATE TABLE clients
( curp CHAR(18) NOT NULL PRIMARY KEY,
cid SERIAL NOT NULL REFERENCES cards,
clocation VARCHAR(29)
) INHERITS (people);
CREATE TABLE cards
( cid BIGSERIAL NOT NULL PRIMARY KEY,
curp CHAR(18) NOT NULL REFERENCES clients,
trips SMALLINT,
distance NUMERIC,
points NUMERIC
);
CREATE TABLE drivers
( curp CHAR(18) NOT NULL PRIMARY KEY,
rfc CHAR(22) NOT NULL UNIQUE,
adress t_adress NOT NULL
) INHERITS (people);
I've tried in PgAdmin 4 making right-click on a new database -> CREATE Script, it opens Query Editor, I copy paste my code and execute it, but it returns:
ERROR: CREATE DATABASE cannot be executed from a function or multi-command string
SQL state: 25001
I've also tried using Query Tool directly from the PgAdmin tools menu with the same results.
The database is created just fine. But if you want to create object in the new DB, you have to connect to it. In any client, including pgAdmin4.
And you cannot run CREATE DATABASE inside of a transaction. Must be committed on it's own. Executing multiple commands at once is automatically wrapped into a single transaction in pgAdmin.
You have to execute CREATE DATABASE mydb; on its own (for instance by selecting only that line and pressing F5 while being connected to any DB, even the maintenance db "postgres". Then click on "Databases" in the object browser in the pgadmin4 main window / tab, hit F5 to refresh the view, click on the new DB, open up a new query tool with the flash icon (in a new window / tab) and execute the rest of your script there.
psql scripts manage by using the meta-command \c to connect to the new db after creating it, within the same session.
Asides:
"database" is no good name for a database.
CREATE TYPE AS (...), but just CREATE TABLE (...). No AS.
And you typically don't want to use the data type CHAR(18). See:
Any downsides of using data type "text" for storing strings?
Get sum of integers for UNIQUE ids
What is the overhead for varchar(n)?
Should I add an arbitrary length limit to VARCHAR columns?
There is the ; missing after the CREATE DATABASE database (and perhaps give the db a better name).

How to link a sequence to a field with PostgreSQL?

In documentation of postgreSQL 9.6, it said to have serial equivalent we have to link the sequence to the field.
https://www.postgresql.org/docs/9.6/datatype-numeric.html (ยค 8.1.4)
I exactly applied the same code :
CREATE SEQUENCE seq_import_trame INCREMENT 1 START 1;
CREATE TABLE import_trame (
id integer NOT NULL DEFAULT nextval('seq_import_trame'),
...,
CONSTRAINT pk_import_trame PRIMARY KEY (id)
);
ALTER SEQUENCE seq_import_trame OWNED BY import_trame.id;
But I have an error while executing script with pgAdmin.
Relation "seq_import_trame" already exist".
Code: 42P07
Line 8: ALTER SEQUENCE.....
It's very strange because 42P07 error is duplicate_table.
And if we don't make the link, the sequence is not dropped when we drop the table.
Any idea ?
I see no problem on DB Fiddle:
Schema (PostgreSQL v9.6)
CREATE SEQUENCE seq_import_trame INCREMENT 1 START 1;
CREATE TABLE import_trame (
id integer NOT NULL DEFAULT nextval('seq_import_trame'),
CONSTRAINT pk_import_trame PRIMARY KEY (id)
);
ALTER SEQUENCE seq_import_trame OWNED BY import_trame.id;
View on DB Fiddle
Check again your script.

Attach sequence to a column and start with 1000

Apply this sql script:
create table software (
id bigint not null,
name varchar(255),
description varchar(255),
constraint pk_software primary key (id))
;
create sequence software_seq;
Then this one:
alter sequence software_seq start with 1000;;
insert into software (id, name, description) values ( 1, 'Soft1', 'Description1');
Then when insert new software programatically (from java), got new software with id = 24
Why not with 1001? Since 'alter sequence software_seq start with 1000;'
You have a few things wrong here.
First of all, just creating a sequence with a particular name doesn't attach it to the table and column that you want using it. You need to change software.id to use software_seq for default values:
alter table software alter column id set default nextval('software_seq');
and you'll want to change the sequence's ownership too (unless of course you're using the sequence in other places):
OWNED BY table_name.column_name
OWNED BY NONE
The OWNED BY option causes the sequence to be associated with a specific table column, such that if that column (or its whole table) is dropped, the sequence will be automatically dropped as well. If specified, this association replaces any previously specified association for the sequence. The specified table must have the same owner and be in the same schema as the sequence. Specifying OWNED BY NONE removes any existing association, making the sequence "free-standing".
So you should:
alter sequence software_seq owned by software.id;
Then when inserting, you'd either leave out the id:
insert into software (name, description) values ('...', '...');
or specify DEFAULT:
insert into software (id, name, description) values (default, '...', '...');
Your other problem is that start with doesn't do what you think it does:
start
The optional clause START WITH start changes the recorded start value of the sequence. This has no effect on the current sequence value; it simply sets the value that future ALTER SEQUENCE RESTART commands will use.
If you want the sequence to start at 1000 then you can:
alter sequence software_seq restart with 1000;
Alternatively, you could use setval:
select setval('software_seq', 1000);
Of course, you could also use bigserial:
The data types smallserial, serial and bigserial are not true types, but merely a notational convenience for creating unique identifier columns (similar to the AUTO_INCREMENT property supported by some other databases). In the current implementation, specifying:
CREATE TABLE tablename (
colname SERIAL
);
is equivalent to specifying:
CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
So using bigserial as the id column type would set up all the sequence stuff for you. Then you'd set the starting value as before using alter sequence or setval.
Probably I got. If one wants to change the sequence, then he should use this syntax:
ALTER SEQUENCE sequenceName [ RESTART WITH long ] [ INCREMENT BY long ]
i.e. use 'RESTART' but not 'START'
I tested: then it really start with 1000 when inserting new value.

How to add a sequence column to an existing table with records

I had created a new table named USERLOG with two fields from a previous VIEW. The table already consist of about 9000 records. The two fields taken from the VIEW, i.e. weblog_views consist of IP (consists of IP address), and WEB_LINK (consists of URL). This is the code I used,
CREATE TABLE USERLOG
AS
SELECT C_IP, WEB_LINK FROM weblog_views;
I want to add another column to this table called the USER_ID, which would consists of a sequence starting with 1 to 9000 records to create a unique id for each existing rows. I need help with this part. I'm using Oracle SQL Developer: ODMiner version 3.0.04.
I tried using the AUTO-INCREMENT option,
ALTER TABLE USERLOG
ADD USER_ID INT UNSIGNED NOT NULL AUTO_INCREMENT;
But I get an error with this,
Error report:
SQL Error: ORA-01735: invalid ALTER TABLE option
01735. 00000 - "invalid ALTER TABLE option"
So, I would really appreciate any help that I can get!
You would need to add a column
ALTER TABLE userlog
ADD( user_id number );
create a sequence
CREATE SEQUENCE user_id_seq
START WITH 1
INCREMENT BY 1
CACHE 20;
Update the data in the table
UPDATE userlog
SET user_id = user_id_seq.nextval
Assuming that you want user_id to be the primary key, you would then add the primary key constraint
ALTER TABLE userlog
ADD CONSTRAINT pk_user_id PRIMARY KEY( user_id );
If you want to use the sequence to automatically add the user_id when you do an INSERT (the other option would be to specifically reference user_id_seq.nextval in your INSERT statements, you would also need a trigger
CREATE OR REPLACE TRIGGER trg_userlog_user_id
BEFORE INSERT ON userlog
FOR EACH ROW
BEGIN
:new.user_id := user_id_seq.nextval;
END;
In addition to Justin's excellent answer you might want to prevent NULL values for your user_id in the future (as they could still be caused by UPDATE statements). Therefore, execute the following statement at the end:
ALTER TABLE userlog MODIFY(user_id number NOT NULL);
Step 1.
Create sequence to be used by the column
eg:
CREATE SEQUENCE user_id_seq
START WITH 1
INCREMENT BY 1
CACHE 20;
Step 2.
Update new column with sequence
eg:
UPDATE userlog
SET user_id = user_id_seq.nextval;
Step 3. - Set Sequence as the default value for the column, will work only above Oracle 12c
ALTER TABLE USERLOG
MODIFY USER_ID INT DEFAULT user_id_seq.nextval;