sql statement error: "column .. does not exist" - sql

Im trying from postgres console this command:
select sim.id as idsim,
num.id as idnum
from main_sim sim
left join main_number num on (FK_Numbers_id=num.id);
and I've got this response:
ERROR: column "fk_numbers_id" does not exist
LINE 1: ...m from main_sim sim left join main_number num on (FK_Numbers...
but if I simply check my table with:
dbMobile=# \d main_sim
id | integer | not null default
Iccid | character varying(19) | not null
...
FK_Device_id | integer |
FK_Numbers_id | integer |
Indexes:
"main_sim_pkey" PRIMARY KEY, btree (id)
"main_sim_FK_Numbers_id_key" UNIQUE, btree ("FK_Numbers_id")
"main_sim_Iccid_key" UNIQUE, btree ("Iccid")
"main_sim_FK_Device_id" btree ("FK_Device_id")
Foreign-key constraints:
"FK_Device_id_refs_id_480a73d1" FOREIGN KEY ("FK_Device_id") REFERENCES main_device(id) DEFERRABLE INITIALLY DEFERRED
"FK_Numbers_id_refs_id_380cb036" FOREIGN KEY ("FK_Numbers_id") REFERENCES main_number(id) DEFERRABLE INITIALLY DEFERRED
...as we can see the column exist.
probably it's syntax error, but I'm unable to see what...
any help will'be appreciated.
Alessio

No, the column FK_Numbers_id does not exist, only a column "FK_Numbers_id" exists
Apparently you created the table using double quotes and therefor all column names are now case-sensitive and you have to use double quotes all the time:
select sim.id as idsim,
num.id as idnum
from main_sim sim
left join main_number num on ("FK_Numbers_id" = num.id);
To recap what is already documented in the manual:
The column foo and FOO are identical, the columns "foo" and "FOO" are not.

Related

Insert multiple values with foreign key Postgresql

I am having trouble figuring out how to insert multiple values to a table, which checks if another table has the needed values stored. I am currently doing this in a PostgreSQL server, but will be implementing it in PreparedStatements for my java program.
user_id is a foreign key which references the primary in mock2. I have been trying to check if mock2 has values ('foo1', 'bar1') and ('foo2', 'bar2').
After this I am trying to insert new values into mock1 which would have a date and integer value and reference the primary key of the row in mock2 to the foreign key in mock1.
mock1 table looks like this:
===============================
| date | time | user_id |
| date | integer | integer |
| | | |
And the table mock2 is:
==================================
| Id | name | program |
| integer | text | test |
Id is a primary key for the table and the name is UNIQUE.
I've been playing around with this solution https://dba.stackexchange.com/questions/46410/how-do-i-insert-a-row-which-contains-a-foreign-key
However, I haven't been able to make it work. Could someone please point out what the correct syntax is for this, I would be really appreciative.
EDIT:
The create table statements are:
CREATE TABLE mock2(
id SERIAL PRIMARY KEY UNIQUE,
name text NOT NULL,
program text NOT NULL UNIQUE
);
and
CREATE TABLE mock1(
date date,
time_spent INTEGER,
user_id integer REFERENCES mock2(Id) NOT NULL);
Ok so I found an answer to my own question.
WITH ins (date,time_spent, id) AS
( VALUES
( '22/08/2012', 170, (SELECT id FROM mock3 WHERE program ='bar'))
)
INSERT INTO mock4
(date, time_spent, user_id)
SELECT
ins.date, ins.time_spent, mock3.id
FROM
mock3 JOIN ins
ON ins.id = mock3.id ;
I was trying to take the 2 values from the first table, match these and then insert 2 new values to the next table, but I realised that I should be using the Primary and Foreign keys to my advantage.
I instead now JOIN on the ID and then just select the key I need by searching it from the values with (SELECT id FROM mock3 WHERE program ='bar') in the third row.

Key is not present in table

table description
# \d invites;
Table "public.invites"
Column | Type | Modifiers
-----------------------+-----------------------------+---------------------
id | integer | not null default
email | character varying |
key | character varying |
sender_user_id | integer | not null
receiver_user_id | integer |
Indexes:
"invites_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"fk_invites_receiver_user_id"
FOREIGN KEY (receiver_user_id) REFERENCES users(id)
"fk_invites_sender_user_id"
FOREIGN KEY (sender_user_id) REFERENCES users(id)
you can see Foreighn Key "fk_invites_receiver_user_id" FOREIGN KEY (receiver_user_id) REFERENCES users(id).
But the records for user with pk is absent in the parent table, where in the reference table fk is exists.
# select id from users where id = 958;
id
----
(0 rows)
select count(*) from invites where receiver_user_id = 958;
count
-------
1
(1 row)
the question is how it can be, simple way to fix the conflicts is delete wrong records, but want to exclude such situation in the future, and when i try to restore the data there is an error:
DETAIL: Key (receiver_user_id)=(958) is not present in table "users".
Command was: ALTER TABLE ONLY invites
ADD CONSTRAINT fk_invites_receiver_user_id
FOREIGN KEY (receiver_user_id) REFERENCES users(id);
P.S.
database=# select version();
version
------------------------------------------------------------------------
PostgreSQL 9.4.14 on x86_64-unknown-linux-gnu,
compiled by gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4, 64-bit
Create fail
-- tmp schema
-- \i tmp.sql
-- tables
CREATE TABLE users
(id serial NOT NULL PRIMARY KEY
, name text
);
CREATE TABLE refs
( user_from INTEGER NOT NULL
, user_to INTEGER NOT NULL
, msg text
);
-- data
INSERT INTO users(name) VALUES ('Alice'), ('Bob');
INSERT INTO refs VALUES (1,2), (1,3);
-- FK constraints
ALTER TABLE refs
ADD CONSTRAINT bad_user_from
FOREIGN KEY (user_from) references users(id);
ALTER TABLE refs
ADD CONSTRAINT bad_user_to
FOREIGN KEY (user_to) references users(id)
NOT VALID ; -- <<--HERE
-- This should fail; user=3 does not exist
INSERT INTO refs VALUES (3,2), (2,3);
Repair
-- "repair" the broken refs (by introducing a dummy row)
INSERT INTO users(id,name) VALUES (0, 'NoName');
-- Make the bad FKs point to the dummy row
UPDATE refs r
SET user_to =0
WHERE NOT EXISTS(
SELECT *
FROM users u
WHERE u.id= r.user_to
);
UPDATE refs r
SET user_from =0
WHERE NOT EXISTS(
SELECT *
FROM users u
WHERE u.id= r.user_from
);
SELECT * FROM refs r
JOIN users u0 ON u0.id= r.user_from
JOIN users u1 ON u1.id= r.user_to
;
INSERT INTO users(name) VALUES ('NewName');
-- see what we'v got
SELECT * FROM users;
SELECT* FROM refs r
JOIN users u0 ON u0.id= r.user_from
JOIN users u1 ON u1.id= r.user_to;
Validate constraint
\d refs
\d users
-- enforce the constraint
ALTER TABLE refs
VALIDATE CONSTRAINT bad_user_to; -- <<-- HERE
-- check if valid
\d refs
\d users
-- This should not fail; user=3 does exist now
INSERT INTO refs VALUES (3,2), (2,3);
The answer is unfortunately “data corruption”.
You should delete the offending row, dump the database with pg_dumpall and restore it into a fresh cluster created with initdb.
You should also try to find out what caused the data corruption. Did you have any crashes recently? Could it be that you have unreliable storage or hardware problems? Anything weird in the database log?
To exclude such problems as much as possible, always use the latest fixpack for your PostgreSQL version and use reliable hardware.

How to re-define indexes in a postgres SQL table

I have this table which is automatically created in my DB.
This is the description of the table using the \d command.
Table "public.tableA":
Column | Type | Modifiers
----------------------------+----------+-----------------------------------------------------
var_a | integer | not null
var_b | integer | not null
var_c | bigint | not null default nextval('var_c_sequence'::regclass)
var_d | integer |
var_e | integer |
var_f | smallint | default mysessionid()
var_g | smallint | default (-1)
var_h | boolean | default false
var_g | uuid |
Indexes:
"tableA_pkey" PRIMARY KEY, btree (var_c)
"tableA_edit" btree (var_g) WHERE var_g <> (-1)
"tableA_idx" btree (var_a)
Check constraints:
"constraintC" CHECK (var_f > 0 AND var_d IS NULL AND var_e IS NULL OR (var_f = 0 OR var_f = (-1)) AND var_d IS NOT NULL AND var_e IS NOT NULL)
Triggers:
object_create BEFORE INSERT ON tableA FOR EACH ROW EXECUTE PROCEDURE create_tableA()
object_update BEFORE DELETE OR UPDATE ON tableA FOR EACH ROW EXECUTE PROCEDURE update_tableA()
I'm interested in creating this table myself, and I'm not quite sure on how to define this indices manually, any ideas?
Unless I've totally missed the boat:
alter table public."tableA"
add constraint "tableA_pkey" PRIMARY KEY (var_c);
create index "tableA_edit" on public."tableA" (var_g) WHERE var_g <> (-1);
create index "tableA_idx" on public."tableA" (var_a);
Btree is default, so I don't bother specifying that, but you can if you want.
You didn't ask, but the check constraint syntax is:
alter table public."tableA"
add constraint "constraintC"
CHECK (var_f > 0 AND var_d IS NULL AND var_e IS NULL OR
(var_f = 0 OR var_f = (-1)) AND var_d IS NOT NULL AND var_e IS NOT NULL)
By the way, the cheat would be to just look at the DDL in PgAdmin.
All that said, I generally discourage the use of the "quoteS" around a table to enforce upper/lowercase. There are cases where it makes sense (otherwise, why would the functionality exist), but in many cases it creates so much extra work in the future. In the case of the index names, it doesn't even buy you anything, since you don't really refer to them in any SQL.

Can't update or delete row from table (Postgres)

I have table with bytea field. When I try to delete a row from this table, I get such error:
[42704] ERROR: large object 0 does not exist
Can you help me in this situation?
Edit. Information from command \d photo:
Table "public.photo"
Column | Type | Modifiers
------------+------------------------+-----------
id | character varying(255) | not null
ldap_name | character varying(255) | not null
file_name | character varying(255) | not null
image_data | bytea |
Indexes:
"pk_photo" PRIMARY KEY, btree (id)
"photo_file_name_key" UNIQUE CONSTRAINT, btree (file_name)
"photo_ldap_name" btree (ldap_name)
Triggers:
remove_unused_large_objects BEFORE DELETE OR UPDATE ON photo FOR EACH ROW EXECUTE PROCEDURE lo_manage('image_data')
Drop the trigger:
drop trigger remove_unused_large_objects on photo;
try using this
delete from photo where primarykey = 'you want to delete';

ERROR: relation "students" already EXISTS

When I am executing this query:
CREATE TABLE public.students (
id INTEGER PRIMARY KEY NOT NULL DEFAULT NEXTVAL('students_id_seq'::regclass),
first_name CHARACTER VARYING(20) NOT NULL,
last_name CHARACTER VARYING(20) NOT NULL,
major CHARACTER VARYING(20) NOT NULL
);
CREATE UNIQUE INDEX "Students_ID_uindex" ON students USING BTREE (id);
SELECT * FROM public.students;
I get the following error:
[2016-03-12 22:16:54] Run postgres.public.students [PostgreSQL - postgres#localhost]
[2016-03-12 22:16:54] Connecting TO PostgreSQL - postgres#localhost...
CREATE TABLE public.students (
id INTEGER PRIMARY KEY NOT NULL DEFAULT NEXTVAL('students_id_seq'::regclass),
first_name CHARACTER VARYING(20) NOT NULL,
last_name CHARACTER VARYING(20) NOT NULL,
major CHARACTER VARYING(20) NOT NULL
)
[2016-03-12 22:16:54] [42P07] ERROR: relation "students" already EXISTS
CREATE UNIQUE INDEX "Students_ID_uindex" ON students USING BTREE (id)
[2016-03-12 22:16:54] [42P07] ERROR: relation "Students_ID_uindex" already EXISTS
SELECT * FROM public.students
[2016-03-12 22:16:54] Executed IN 14ms ms
[2016-03-12 22:16:54] Summary: 3 OF 3 statements executed, 2 failed IN 68ms (338 symbols IN file)
I have made the table using DataGrip generate:
Any idea what am I doing wrong?
UPDATE: Just to clarify my question, when I first run the code with a new table name, I get now error but when I run it again I get the above error. How can this be fixed?
You cannot create more tables with the same name - so statement CREATE should fail if there is a table with the same name already.
You can run the statement DROP TABLE before - but be aware! - it drops the table with all it's data, and undo is not possible. Second alternative is using the clause IF NOT EXISTS in CREATE statement:
DROP TABLE IF EXISTS foo;
CREATE TABLE foo(a int);
or
CREATE TABLE IF NOT EXISTS foo(a int);
You don't need to use an index name, just allow to PG to made it by itselves:
CREATE INDEX name ON public.students ("id");