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

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';

Related

How to declare "nextval('testing_thing_thing_id_seq'::regclass)" as default value for column "thing_id" in postgres table "testing_thing"?

In my postgres db there is a table called testing_thing, which I can see (by running \d testing_thing in my psql prompt) it is defined as
Table "public.testing_thing"
Column | Type | Collation | Nullable | Default
--------------+-------------------+-----------+----------+-----------------------------------------------------
thing_id | integer | | not null | nextval('testing_thing_thing_id_seq'::regclass)
thing_num | smallint | | not null | 0
thing_desc | character varying | | not null |
Indexes:
"testing_thing_pk" PRIMARY KEY, btree (thing_num)
I want to drop it and re-create it exactly as it is, but I don't know how to reproduce the
nextval('testing_thing_thing_id_seq'::regclass)
part for column thing_id.
This is the query I put together to create the table:
CREATE TABLE testing_thing(
thing_id integer NOT NULL, --what else should I put here?
thing_num smallint NOT NULL PRIMARY KEY DEFAULT 0,
thing_desc varchar(100) NOT NULL
);
what is it missing?
Add a DEFAULT to the column you want to increment and call nextval():
CREATE SEQUENCE testing_thing_thing_id_seq START WITH 1;
CREATE TABLE testing_thing(
thing_id integer NOT NULL DEFAULT nextval('testing_thing_thing_id_seq'),
thing_num smallint NOT NULL PRIMARY KEY DEFAULT 0,
thing_desc varchar(100) NOT NULL
);
Side note: Keep in mind that attaching a sequence to a column does not prevent users to manually fill it with random data, which can create really nasty problems with primary keys. If you want to overcome it and do not necessarily need to have a sequence, consider creating an identity column, e.g.
CREATE TABLE testing_thing(
thing_id integer NOT NULL GENERATED ALWAYS AS IDENTITY,
thing_num smallint NOT NULL PRIMARY KEY DEFAULT 0,
thing_desc varchar(100) NOT NULL
);
Demo: db<>fiddle

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.

copy table (create table like) - not keeping auto incrementing primary key

I'm new to postgres (on 9.5) and I can't find this in the docs anywhere.
Basically create a table like this:
CREATE TABLE test (
id serial primary key,
field1 CHARACTER VARYING(50)
);
Then copy it:
create table test_copy (like test);
The table test has these columns:
COLUMN_NAME id field1
DATA_TYPE 4 12
TYPE_NAME serial varchar
COLUMN_SIZE 10 50
IS_NULLABLE NO YES
IS_AUTOINCREMENT YES NO
But test_copy has these:
COLUMN_NAME id field1
DATA_TYPE 4 12
TYPE_NAME int4 varchar
COLUMN_SIZE 10 50
IS_NULLABLE NO YES
IS_AUTOINCREMENT NO NO
Why am I losing serial and autoincrement? How can I make a copy of a table that preserves these?
This is because serial isn't really a datatype. It gets "expanded" to an integer + a sequence + a default value.
See the manual for details
To get the default definition you need to use create table test_copy (like test INCLUDING DEFAULTS).
However, that will then use the same sequence as the original table.
You can see the difference when you display the table definition in psql:
psql (9.5.3)
Type "help" for help.
postgres=> CREATE TABLE test (
postgres(> id serial primary key,
postgres(> field1 CHARACTER VARYING(50)
postgres(> );
CREATE TABLE
postgres=> create table test_copy_no_defaults (like test);
CREATE TABLE
postgres=> create table test_copy (like test including defaults);
CREATE TABLE
postgres=> \d test
Table "public.test"
Column | Type | Modifiers
--------+-----------------------+---------------------------------------------------
id | integer | not null default nextval('test_id_seq'::regclass)
field1 | character varying(50) |
Indexes:
"test_pkey" PRIMARY KEY, btree (id)
postgres=> \d test_copy
Table "public.test_copy"
Column | Type | Modifiers
--------+-----------------------+---------------------------------------------------
id | integer | not null default nextval('test_id_seq'::regclass)
field1 | character varying(50) |
postgres=> \d test_copy_no_defaults
Table "public.test_copy_no_defaults"
Column | Type | Modifiers
--------+-----------------------+-----------
id | integer | not null
field1 | character varying(50) |
you can try:
create table test_inh () inherits (test);
and then
alter table test_inh no inherit test;
should leave same sequence default value for you

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

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.

MySQL: Which indexes to use for a simple range select?

I have a table with ~30 million rows ( and growing! ) and currently i have some problems with a simple range select.
The query, looks like this one:
SELECT SUM( CEIL( dlvSize / 100 ) ) as numItems
FROM log
WHERE timeLogged BETWEEN 1000000 AND 2000000
AND user = 'example'</pre>
It takes minutes to finish and i think that the solution would be at the indexes that i'm using. Here is the result of explain:
+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+
| 1 | SIMPLE | log | range | PRIMARY,timeLogged | PRIMARY | 4 | NULL | 11839754 | Using where |
+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+
My table structure is this one ( reduced to make it fit better on the problem ):
CREATE TABLE IF NOT EXISTS `log` (
`origDomain` varchar(64) NOT NULL default '0',
`timeLogged` int(11) NOT NULL default '0',
`orig` varchar(128) NOT NULL default '',
`rcpt` varchar(128) NOT NULL default '',
`dlvSize` varchar(255) default NULL,
`user` varchar(255) default NULL,
PRIMARY KEY (`timeLogged`,`orig`,`rcpt`),
KEY `timeLogged` (`timeLogged`),
KEY `orig` (`orig`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Any ideas of what can I do to optimize this query or indexes on my table?
You may want to try adding a composite index on (user, timeLogged):
CREATE TABLE IF NOT EXISTS `log` (
...
KEY `user_timeLogged` (user, timeLogged),
...
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Related Stack Overflow post:
Database: When should I use a composite index?
In addition to the suggestions made by the other answers, I note that you have a column user in the table which is a varchar(255). If this refers to a column in a table of users, then 1) it would most likely to far more efficient to add an integer ID column to that table, and use that as the primary key and as a referencing column in other tables; 2) you are using InnoDB, so why not take advantage of the foreign key capabilities it offers?
Consider that if you index by a varchar(n) column, it is treated like a char(n) in the index, so each row of your current primary key takes up 4 + 128 + 128 = 260 bytes in the index.
Add an index on user.