how to move tables from public to other schema in Postgres - sql

Postgres 9.1 database contains tables yksus1 .. ykssu9 in public schema. pgAdmin shows those definitions as in code below.
How to move those tables to firma1 schema ?
Other tables in firma1 schema have foreign key references to those table primay keys. Foreign key references to those tables are only from tables in firma1 schema.
Some of those tables contain data.
If tables is moved to firma1 schema, foreign key references shouuld also be updated to firma1.yksusn tables.
Table structures cannot changed.
It looks like primary key sequences are already in firma1 schema so those should not moved.
Version string PostgreSQL 9.1.2 on x86_64-unknown-linux-gnu, compiled by gcc-4.4.real (Debian 4.4.5-8) 4.4.5, 64-bit
CREATE TABLE yksus1
(
yksus character(10) NOT NULL DEFAULT ((nextval('firma1.yksus1_yksus_seq'::regclass))::text || '_'::text),
veebis ebool,
nimetus character(70),
"timestamp" character(14) DEFAULT to_char(now(), 'YYYYMMDDHH24MISS'::text),
username character(10) DEFAULT "current_user"(),
klient character(40),
superinden character(20),
telefon character(10),
aadress character(50),
tlnr character(15),
rus character(60),
CONSTRAINT yksus1_pkey PRIMARY KEY (yksus)
);
ALTER TABLE yksus1
OWNER TO mydb_owner;
CREATE TRIGGER yksus1_trig
BEFORE INSERT OR UPDATE OR DELETE
ON yksus1
FOR EACH STATEMENT
EXECUTE PROCEDURE setlastchange();
other tables are similar:
CREATE TABLE yksus2
(
yksus character(10) NOT NULL DEFAULT ((nextval('firma1.yksus2_yksus_seq'::regclass))::text || '_'::text),
nimetus character(70),
"timestamp" character(14) DEFAULT to_char(now(), 'YYYYMMDDHH24MISS'::text),
osakond character(10),
username character(10) DEFAULT "current_user"(),
klient character(40),
superinden character(20),
telefon character(10),
aadress character(50),
tlnr character(15),
rus character(60),
CONSTRAINT yksus2_pkey PRIMARY KEY (yksus),
CONSTRAINT yksus2_osakond_fkey FOREIGN KEY (osakond)
REFERENCES yksus2 (yksus) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION DEFERRABLE INITIALLY IMMEDIATE
);
ALTER TABLE yksus2
OWNER TO mydb_owner;
CREATE TRIGGER yksus2_trig
BEFORE INSERT OR UPDATE OR DELETE
ON yksus2
FOR EACH STATEMENT
EXECUTE PROCEDURE setlastchange();

ALTER TABLE yksus1
SET SCHEMA firma1;
More details in the manual: http://www.postgresql.org/docs/current/static/sql-altertable.html
Associated indexes, constraints, and sequences owned by table columns are moved as well.
Not sure about the trigger function though, but there is an equivalent ALTER FUNCTION .. SET SCHEMA ... as well.

Related

How to execute an unordered SQL script

I have a SQL script but there is an issue with the order of the statements in the script
e.g.
INSERT INTO PERMISSIONS_FOR_ROLE (ROLE_ID, PERMISSION_ID) VALUES (3, 8);
INSERT INTO permissions (id, name) VALUES (8, 'update');
The order of occurrence in the script should have been reverse! And this results in a error because the foreign key with id 8 is not yet inserted when the first statement executes
leading to:
[Code: -177, SQL State: 23503] integrity constraint violation:
foreign key no parent; PERMISSIONS_FOR_ROLE_PERM_FK table: PERMISSIONS_FOR_ROLE value: 8
statements used to create the relationships are as below
create table PERMISSIONS ( ID bigint not null, NAME varchar(255), primary key (ID) );
create table PERMISSIONS_FOR_ROLE ( ROLE_ID bigint not null, PERMISSION_ID bigint not null, primary key (ROLE_ID, PERMISSION_ID) );
alter table PERMISSIONS_FOR_ROLE add constraint permissions_for_role_perm_fk foreign key (PERMISSION_ID) references PERMISSIONS;
Any suggestions on how to execute such a script ? I tried manually changing the order and the script executes properly but is there any other way to do it as its run as part of a ANT build target.
For mass inserts with very large scripts that are out of order, you can disable referential integrity checks with:
SET DATABASE REFERENTIAL INTEGRITY FALSE
see http://hsqldb.org/doc/2.0/guide/management-chapt.html#mtc_sql_settings on how to check for possible violations after the insert.

Postgres breaking null constraint on a serial column

I have a table that I create independently, the primary key is set with the serial type and a sequence applied to the table, but when I try to insert a value a NULL CONSTRAINT error is thrown and the return looks like null was passed, am I missing something in the INSERT statement?
SQL for table generation:
DROP TABLE IF EXISTS public."Team" CASCADE;
CREATE TABLE public."Team" (
"IdTeam" serial PRIMARY KEY,
name text NOT null,
CONSTRAINT "pKeyTeamUnique" UNIQUE ("IdTeam")
);
ALTER TABLE public."Team" OWNER TO postgres;
DROP SEQUENCE IF EXISTS public."Team_IdTeam_seq" CASCADE;
CREATE SEQUENCE public."Team_IdTeam_seq"
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE public."Team_IdTeam_seq" OWNER TO postgres;
ALTER SEQUENCE public."Team_IdTeam_seq" OWNED BY public."Team"."IdTeam";
SQL for insert :
INSERT INTO public."Team" (name) values ('Manchester Untited');
The returning error:
ERROR: null value in column "IdTeam" violates not-null constraint
DETAIL: Failing row contains (null, Manchester Untited).
SQL state: 23502
I am baffled. Why are you trying to define your own sequence when the column is already defined as serial?
Second, a primary key constraint is already unique. There is no need for a separate unique constraint.
Third, quoting identifiers just makes the code harder to write and to read.
You can just do:
DROP TABLE IF EXISTS public.Team CASCADE;
CREATE TABLE public.Team (
IdTeam serial PRIMARY KEY,
name text NOT null
);
INSERT INTO public.Team (name)
VALUES ('Manchester Untited');
Dropping the sequence causes the default definition for the IdTeam column to be dropped. After recreating the sequence you will have to recreate the default definition.

Remove Unique constraint on a column in sqlite database

I am trying to remove a UNIQUE constraint on a column for sqlite but I do not have the name to remove the constraint. How can I find the name of the UNIQUE constraint name to remove it.
Below is the schema I see for the table I want to remove the constraint
UNIQUE (datasource_name)
sqlite> .schema datasources
CREATE TABLE "datasources" (
created_on DATETIME NOT NULL,
changed_on DATETIME NOT NULL,
id INTEGER NOT NULL,
datasource_name VARCHAR(255),
is_featured BOOLEAN,
is_hidden BOOLEAN,
description TEXT,
default_endpoint TEXT,
user_id INTEGER,
cluster_name VARCHAR(250),
created_by_fk INTEGER,
changed_by_fk INTEGER,
"offset" INTEGER,
cache_timeout INTEGER, perm VARCHAR(1000), filter_select_enabled BOOLEAN, params VARCHAR(1000),
PRIMARY KEY (id),
CHECK (is_featured IN (0, 1)),
CHECK (is_hidden IN (0, 1)),
FOREIGN KEY(created_by_fk) REFERENCES ab_user (id),
FOREIGN KEY(changed_by_fk) REFERENCES ab_user (id),
FOREIGN KEY(cluster_name) REFERENCES clusters (cluster_name),
UNIQUE (datasource_name),
FOREIGN KEY(user_id) REFERENCES ab_user (id)
);
SQLite only supports limited ALTER TABLE, so you can't remove the constaint using ALTER TABLE. What you can do to "drop" the column is to rename the table, create a new table with the same schema except for the UNIQUE constraint, and then insert all data into the new table. This procedure is documented in the Making Other Kinds Of Table Schema Changes section of ALTER TABLE documentation.
I just ran into this myself. An easy solution was using DB Browser for SQLite
It let me remove a unique constraint with just a checkbox in a gui.
PRAGMA foreign_keys=off;
BEGIN TRANSACTION;
ALTER TABLE table_name RENAME TO old_table;
CREATE TABLE table_name
(
column1 datatype [ NULL | NOT NULL ],
column2 datatype [ NULL | NOT NULL ],
...
);
INSERT INTO table_name SELECT * FROM old_table;
COMMIT;
PRAGMA foreign_keys=on;
Source: https://www.techonthenet.com/sqlite/unique.php
I was just working through this issue on a small database and found it easier to dump the data as SQL statements, it prints out your tables exactly as they are and also adds the INSERT INTO statements to rebuild the DB.
The .help terminal command shows:
.dump ?OBJECTS? Render database content as SQL
and prints the SQL to the terminal, you can update it in a TXT file. For once off changes and tidying this seems like a reasonable solution albeit a little inelegant

Errors in my schema creation script

So I have a simple SQL script which creates a database schema of a simple library online catalog:
DROP TABLE book_copies;
/
DROP TABLE books_authors_xref;
/
DROP TABLE authors;
/
DROP TABLE books;
/
CREATE TABLE books (
isbn VARCHAR2(13) NOT NULL PRIMARY KEY,
title VARCHAR2(200),
summary VARCHAR2(2000),
date_published DATE,
page_count NUMBER
);
/
CREATE TABLE authors (
name VARCHAR2(200) NOT NULL PRIMARY KEY
);
/
CREATE TABLE books_authors_xref (
author_name VARCHAR2(200),
book_isbn VARCHAR2(13),
CONSTRAINT pk_books_authors_xref PRIMARY KEY (author_name, book_isbn),
CONSTRAINT fk_books_authors_xref1 FOREIGN KEY (author_name) REFERENCES authors (name),
CONSTRAINT fk_books_authors_xref2 FOREIGN KEY (book_isbn) REFERENCES books (isbn)
);
/
CREATE TABLE book_copies (
barcode_id VARCHAR2(100) NOT NULL PRIMARY KEY,
book_isbn VARCHAR2(13),
CONSTRAINT fk_book_copies FOREIGN KEY (book_isbn) REFERENCES books (isbn)
);
/
Whenever I run it through SQL*Plus, I get many errors during its execution even though it looks like all SQL orders execute properly. This is the output I get:
What does that mean? Am I doing something wrong?
The / in SQL*Plus executes the "command in the buffer". A statement terminated with a semicolon is executed and put into the buffer.
So the CREATE TABLE books .... is actually run twice. The first time because of the semicolon ; (which puts the statement into the buffer) and the second time when the parser hits the /.
That's why you get the "name is already used" error.
So you need to use either a semicolon or a slash, but not both.
Edit
You can see what's going on, when manually running a statement using both, in the following log I copied & pasted the first statement from your script to a SQL*Plus console:
SQL> DROP TABLE book_copies;
Table dropped.
SQL> /
DROP TABLE book_copies
*
ERROR at line 1:
ORA-00942: table or view does not exist
You can see clearly how the DROP TABLE is execute because of the semicolon, and how the / executes it again.

SQL Server 2005: Nullable Foreign Key Constraint

I have a foreign key constraint between tables Sessions and Users. Specifically, Sessions.UID = Users.ID. Sometimes, I want Sessions.UID to be null. Can this be allowed? Any time I try to do this, I get an FK Constraint Violation.
Specifically, I'm inserting a row into Sessions via LINQ. I set the Session.User = null; and I get this error:
An attempt was made to remove a relationship between a User and a Session. However, one of the relationship's foreign keys (Session.UID) cannot be set to null.
However, when I remove the line that nulls the User property, I get this error on my SubmitChanges line:
Value cannot be null.
Parameter name: cons
None of my tables have a field called 'cons', nor is it in my 5,500-line DataContext.designer.cs file, nor is it in the QuickWatch for any of the related objects, so I have no idea what 'cons' is.
In the Database, Session.UID is a nullable int field and User.ID is a non-nullable int. I want to record sessions that may or may not have a UID, and I'd rather do it without disabling constraint on that FK relationship. Is there a way to do this?
I seemed to remember creating a nullable FK before, so I whipped up a quick test. As you can see below, it is definitely doable (tested on MSSQL 2005).
Script the relevant parts of your tables and constraints and post them so we can troubleshoot further.
CREATE DATABASE [NullableFKTest]
GO
USE [NullableFKTest]
GO
CREATE TABLE OneTable
(
OneId [int] NOT NULL,
CONSTRAINT [PK_OneTable] PRIMARY KEY CLUSTERED
(
[OneId] ASC
)
)
CREATE TABLE ManyTable (ManyId [int] IDENTITY(1,1) NOT NULL, OneId [int] NULL)
GO
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_ManyTable_OneTable]') AND parent_object_id = OBJECT_ID(N'[dbo].[ManyTable]') )
ALTER TABLE [dbo].[ManyTable] WITH CHECK ADD CONSTRAINT [FK_ManyTable_OneTable] FOREIGN KEY([OneId])
REFERENCES [dbo].[OneTable] ([OneId])
GO
--let's get a value in here
insert into OneTable(OneId) values(1)
select* from OneTable
--let's try creating a valid relationship to the FK table OneTable
insert into ManyTable(OneId) values (1) --fine
--now, let's try NULL
insert into ManyTable(OneId) values (NULL) --also fine
--how about a non-existent OneTable entry?
insert into ManyTable(OneId) values (5) --BOOM! - FK violation
select* from ManyTable
--1, 1
--2, NULL
--cleanup
ALTER TABLE ManyTable DROP CONSTRAINT FK_ManyTable_OneTable
GO
drop TABLE OneTable
GO
drop TABLE ManyTable
GO
USE [Master]
GO
DROP DATABASE NullableFKTest