Why deleting from a table does not work in PostgreSQL - sql

I tried deleting a row from a table but the result was
DELETE 0
When I created a copy of the original table and performed the delete on the new copy-table
the result was: DELETE 1 as expected
I've created a trigger function that updates a column on a different table upon inserting or deleting is there an option that this is the problem?
Does anyone know what might be the problem ??
P.S. I post a similar to the creation code of the original table because it has been altered for the next parts of the university project and the trigger function's code
P.S.2 A friend who has the same exact database, table, trigger function etc.
doesn't have this problem
create table Listings(
id int,
listing_url varchar(40),
scrape_id bigint,
last_scraped date,
name varchar(140),
summary varchar(1780),
space varchar(1840),
description varchar(2320),
experiences_offered varchar(10),
neighborhood_overview varchar(1830),
notes varchar(1790),
transit varchar(1810),
access varchar(1830),
interaction varchar(1340),
house_rules varchar(1820),
thumbnail_url varchar(10),
medium_url varchar(10),
picture_url varchar(150),
xl_picture_url varchar(10),
street varchar(90),
neighbourhood varchar(20),
neighbourhood_cleansed varchar(70),
neighbourhood_group_cleansed varchar(10),
city varchar(40),
state varchar(60),
zipcode varchar(20),
market varchar(30),
smart_location varchar(40),
country_code varchar(10),
country varchar(10),
latitude varchar(10),
longitude varchar(10),
is_location_exact boolean,
property_type varchar(30),
room_type varchar(20),
accommodates int,
bathrooms varchar(10),
bedrooms int,
beds int,
bed_type varchar(20),
amenities varchar(1660),
);
CREATE FUNCTION Vs()
RETURNS "trigger" AS
$Body$
BEGIN
IF(TG_OP='INSERT')THEN
UPDATE "Host"
SET listings_count = listings_count + 1
WHERE id = NEW.host_id;
RETURN NEW;
ELSIF(TG_OP='DELETE')THEN
UPDATE "Host"
SET listings_count = listings_count -1
WHERE id = OLD.host_id;
RETURN OLD;
END IF;
END;
$Body$
LANGUAGE 'plpgsql' VOLATILE;
CREATE TRIGGER InsertTrigger
before INSERT
ON "Listing"
FOR EACH ROW
EXECUTE PROCEDURE Vs();
CREATE TRIGGER DeleteTrigger
before DELETE
ON "Listing"
FOR EACH ROW
EXECUTE PROCEDURE Vs();

Related

Why am I getting "Error converting data type varchar to int."

I am creating a mock database for a fictional gym. I have 3 relevant tables: Program, Workouts and Exercises (see below). Each Program contains one or many Workouts and each Workout contains one or many Exercises. I am trying to create a stored procedure to add rows to these three tables. I keep getting the error "Error converting data type varchar to int.". I can't understand why because the variable datatypes all match the datatypes in the tables (as far as I can see).
CREATE TABLE [Program]
(
[ProgramID] INT IDENTITY(1,1),
[MemberNumber] INT,
[TrainerID] INT,
[ProgramStartDate] DATE,
[TrainerReviewDate] DATE,
[Active] CHAR(1),
PRIMARY KEY ([ProgramID]),
FOREIGN KEY ([MemberNumber])
REFERENCES [Members] ([MemberNumber])
ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY ([TrainerID])
REFERENCES [Trainers] ([TrainerID])
ON DELETE SET NULL ON UPDATE CASCADE
);
CREATE TABLE [Workouts]
(
[WorkoutID] INT IDENTITY(1,1),
[Description] VARCHAR(50),
[Day] VARCHAR(10),
[ProgramID] INT,
PRIMARY KEY ([WorkoutID]),
FOREIGN KEY ([ProgramID])
REFERENCES [Program] ([ProgramID])
ON DELETE SET NULL ON UPDATE CASCADE
);
CREATE TABLE [Exercise]
(
[ExerciseID] INT IDENTITY(1,1),
[ExerciseType] VARCHAR(30),
[Equipment] VARCHAR(30),
[Sets] INT,
[Reps] INT,
[WorkoutID] INT,
PRIMARY KEY ([ExerciseID]),
FOREIGN KEY ([WorkoutID])
REFERENCES [Workouts] ([WorkoutID])
ON DELETE SET NULL ON UPDATE CASCADE
)
/*Description: This stored procedure adds a new program with workout/exercise details. */
CREATE PROCEDURE usp_New_Program_4 (
#MemberNumber int,
#TrainerID int,
#ProgramStartDate date,
#TrainerReviewDate date,
#Active char(1),
#Description varchar(50),
#Day varchar(10),
#ProgramID int = SCOPE_IDENTITY,
#ExerciseType_1 varchar(30),
#Equipment_1 varchar(30),
#Sets_1 int,
#Reps_1 int,
#ExerciseType_2 varchar(30),
#Equipment_2 varchar(30),
#Sets_2 int,
#Reps_2 int,
#ExerciseType_3 varchar(30),
#Equipment_3 varchar(30),
#Sets_3 int,
#Reps_3 int,
#ExerciseType_4 varchar(30),
#Equipment_4 varchar(30),
#Sets_4 int,
#Reps_4 int,
#WorkoutID int = SCOPE_IDENTITY
)
AS
SET xact_abort ON
BEGIN
INSERT INTO Program (MemberNumber, TrainerID, ProgramStartDate, TrainerReviewDate, Active)
VALUES (#MemberNumber, #TrainerID, #ProgramStartDate, #TrainerReviewDate, #Active);
INSERT INTO Workouts (Description, Day, ProgramID)
VALUES (#Description, #Day, SCOPE_IDENTITY());
INSERT INTO Exercise (ExerciseType, Equipment, Sets, Reps, WorkoutID)
VALUES (#ExerciseType_1, #Equipment_1, #Sets_1, #Reps_1, SCOPE_IDENTITY()),
(#ExerciseType_2, #Equipment_2, #Sets_2, #Reps_2, SCOPE_IDENTITY()),
(#ExerciseType_3, #Equipment_3, #Sets_3, #Reps_3, SCOPE_IDENTITY()),
(#ExerciseType_4, #Equipment_4, #Sets_4, #Reps_4, SCOPE_IDENTITY())
END;
GO
/*Test for usp_New_Program_4
Result: Failed - Error converting data type varchar to int*/
Exec usp_New_Program_4 21,3,'2020-06-06','2020-07-07','Y','Chest & Arms',SCOPE_IDENTITY,'Bench
Press','50kg Barbell',3,6,'Press Ups','Floor Mat',3,15,'Bicep Curls','15kg
Dumbells',3,6,'Tricep Extensions','15kg Dumbells',3,6,SCOPE_IDENTITY
Go
It looks like you may have missed a field in your line to execute the stored procedure. I quickly copied the stored proc input values into a spreadsheet followed by the values in your test line that throws the error. Have a look, it looks like you're missing perhaps the Day value? After that is entered it should line everything up correctly. I marked up the first line that after a quick glance looks like it is causing the error (others lower will too though, until the missing value is fixed).
Basic debugging would be to check your parameters... And if we do that...
Exec usp_New_Program_4 21, --#MemberNumber int
3, --#TrainerID int
'2020-06-06', --#ProgramStartDate date
'2020-07-07', --#TrainerReviewDate date
'Y', --#Active char(1)
'Chest & Arms', --#Description varchar(50)
SCOPE_IDENTITY, --#Day varchar(10)
'Bench
Press', --#ProgramID int
'50kg Barbell', --#ExerciseType_1 varchar(30)
3, --#Equipment_1 varchar(30)
6, --#Sets_1 int
'Press Ups', --#Reps_1 int
'Floor Mat', --#ExerciseType_2 varchar(30)
3, --#Equipment_2 varchar(30)
15, --#Sets_2 int
'Bicep Curls', --#Reps_2 int
'15kg
Dumbells', --#ExerciseType_3 varchar(30)
3, --#Equipment_3 varchar(30)
6, --#Sets_3 int
'Tricep Extensions', --#Reps_3 int
'15kg Dumbells', --#ExerciseType_4 varchar(30)
3, --#Equipment_4 varchar(30)
6, --#Sets_4 int
SCOPE_IDENTITY --#Reps_4 int
Pretty clear now. The value 'Bench
Press' is not an int. Neither are 'Press Ups'
, 'Bicep Curls' or 'Tricep Extensions'.
This is why using the format EXEC PROC {Proc Name} #{Parameter Name} = {Parameter Value} is really important for any procedures that have more than 1 or 2 parameters; you don't make simple mistakes like missing a parameter out.
In this case, you clearly missed out a value for #Day (as I assume you wanted to pass SCOPE_IDENTITY for #ProgramID), and thus all your parameters after that are wrong. The SP still ran fine though, as your last parameter (#WorkoutID) has a default value, and so didn't "mind" being omitted.

Is there way to create trigger for get ref value when insert data?

I create table using types in oracle. I have data file in csv. I need to get ref value for patient table when inserting data.
CREATE TYPE Location_t as OBJECT(
L_id varchar(6),
lon NUMBER(9,6),
lat NUMBER(9,6),
country varchar(26),
Province varchar(26)
)
/
create type patient_t as object(
p_id varchar(10),
ReportedDate date,
Deadts int,
recover int,
confirmed int,
loc ref location_t
)
create table Location of location_t
(L_id PRIMARY KEY)
/
CREATE TABLE PATIENT of patient_t
(p_id PRIMARY KEY,
loc references Location)
Location table data is already inserted and i need to get ref code for patient.
location table
patient table

External table syntax error KUP-01005 Oracle

I receive error as below every time when i select external table that i have created.
ORA-29913: bład podczas wykonywania wywołania (callout) ODCIEXTTABLEOPEN
ORA-29400: bład kartrydza danych
KUP-00554: error encountered while parsing access parameters
KUP-01005: syntax error: found "minussign": expecting one of: "badfile, byteordermark, characterset, column, data, delimited, discardfile, dnfs_enable, dnfs_disable, disable_directory_link_check, field, fields, fixed, io_options, load, logfile, language, nodiscardfile, nobadfile, nologfile, date_cache, dnfs_readbuffers, preprocessor, readsize, string, skip, territory, variable, xmltag"
KUP-01007: at line 4 column 23
29913. 00000 - "error in executing %s callout"
The external table is created successfully. Here is the script which creates external table:
CREATE TABLE TB_CNEI_01C
(
NEW_OMC_ID VARCHAR(2),
NEW_OMC_NM VARCHAR(8),
NEW_BSS_ID VARCHAR(6),
NEW_BSS_NM VARCHAR(20),
OMC_ID VARCHAR(2),
OMC_NM VARCHAR(8),
OLD_BSS_ID VARCHAR(6),
OLD_BSS_NM VARCHAR(20),
DEPTH_NO INTEGER,
NE_TP_NO INTEGER,
OP_YN INTEGER,
FAC_ALIAS_NM VARCHAR(20),
FAC_GRP_ALIAS_NM VARCHAR(20),
SPC_VAL VARCHAR(4),
INMS_FAC_LCLS_CD VARCHAR(2),
INMS_FAC_MCLS_CD VARCHAR(3),
INMS_FAC_SCLS_CD VARCHAR(3),
INMS_FAC_SCLS_DTL_CD VARCHAR(2),
LDEPT_ID VARCHAR(3),
FAC_ID VARCHAR(15),
MME_IP_ADDR VARCHAR(20),
MDEPT_ID VARCHAR(4),
HW_TP_NM VARCHAR(20),
MME_POOL_NM VARCHAR(20),
BORD_CNT INTEGER,
FAC_DTL_CLSFN_NM VARCHAR(50),
INSTL_FLOOR_NM VARCHAR(20),
INSTL_LOC_NM VARCHAR(30)
)
ORGANIZATION EXTERNAL
(
TYPE oracle_loader
DEFAULT DIRECTORY EXTERNAL_DATA
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE
badfile EXTERNAL_DATA:'testTable.bad'
logfile EXTERNAL_DATA:'testTable.log'
CHARACTERSET x-IBM949
FIELDS TERMINATED BY ','
MISSING FIELD VALUES ARE NULL
(
NEW_OMC_ID VARCHAR(2),
NEW_OMC_NM VARCHAR(8),
NEW_BSS_ID VARCHAR(6),
NEW_BSS_NM VARCHAR(20),
OMC_ID VARCHAR(2),
OMC_NM VARCHAR(8),
OLD_BSS_ID VARCHAR(6),
OLD_BSS_NM VARCHAR(20),
DEPTH_NO INTEGER,
NE_TP_NO INTEGER,
OP_YN INTEGER,
FAC_ALIAS_NM VARCHAR(20),
FAC_GRP_ALIAS_NM VARCHAR(20),
SPC_VAL VARCHAR(4),
INMS_FAC_LCLS_CD VARCHAR(2),
INMS_FAC_MCLS_CD VARCHAR(3),
INMS_FAC_SCLS_CD VARCHAR(3),
INMS_FAC_SCLS_DTL_CD VARCHAR(2),
LDEPT_ID VARCHAR(3),
FAC_ID VARCHAR(15),
MME_IP_ADDR VARCHAR(20),
MDEPT_ID VARCHAR(4),
HW_TP_NM VARCHAR(20),
MME_POOL_NM VARCHAR(20),
BORD_CNT INTEGER,
FAC_DTL_CLSFN_NM VARCHAR(50),
INSTL_FLOOR_NM VARCHAR(20),
INSTL_LOC_NM VARCHAR(30)
)
)
LOCATION ('TB_CNEI_01C.csv')
);
I have checked all permisions for data directory and data files
I had a few commented lines in my 'CREATE TABLE ..' script. I removed those commented lines and the error disappeared.
I received the above suggestion from : http://www.orafaq.com/forum/t/182288/
It seems your CHARACTERSET(x-IBM949) containing - character is not valid
You may try the other alternatives without that sign,
such as
AL32UTF8, US7ASCII, WE8MSWIN1252 .. etc.

Postgresql SET DEFAULT value from another table SQL

I'm making a sql script so I have create tables, now I have a new table that have columns. One column has a FOREIGN KEY so I need this value to be SET DEFAULT at the value of the value of the original table. For example consider this two table
PERSON(Name,Surename,ID,Age);
EMPLOYER(Name,Surname,Sector,Age);
In Employer I need AGE to be setted on default on the AGE of Person, this only if PERSON have rows or just 1 row.
ID is Primary key for person and Surname,Sector for employer and AGE is FOREIGN KEY in Employer refferenced from Person
Example sql :
CREATE TABLE PERSON(
name VARCHAR(30) ,
surename VARCHAR(20),
ID VARCHAR(50) PRIMARY KEY,
Age INT NOT NULL,
);
CREATE TABLE EMPLOYER(
name VARCHAR(30) ,
Surename VARCHAR(20),
Sector VARCHAR(20),
Age INT NOT NULL,
PRIMARY KEY (Surename,Sector),
FOREIGN KEY (Age) REFERENCES Person(Age) //HERE SET DEFAULT Person(Age), how'??
);
Taking away the poor design choices of this exercise it is possible to assign the value of a column to that of another one using a trigger.
Rough working example below:
create table a (
cola int,
colb int) ;
create table b (
colc int,
cold int);
Create or replace function fn()
returns trigger
as $$ begin
if new.cold is null then
new.cold = (select colb from a where cola = new.colc);
end if;
return new;
end;
$$ language plpgsql;
CREATE TRIGGER
fn
BEFORE INSERT ON
b
FOR EACH ROW EXECUTE PROCEDURE
fn();
Use a trigger rather than a default. I have done things like this (useful occasionally for aggregated full text vectors among other things).
You cannot use a default here because you have no access to the current row data. Therefore there is nothing to look up if it is depending on your values currently being saved.
Instead you want to create a BEFORE trigger which sets the value if it is not set, and looks up data. Note that this has a different limitation because DEFAULT looks at the query (was a value specified) while a trigger looks at the value (i.e. what does your current row look like). Consequently a default can be avoided by explicitly passing in a NULL. But a trigger will populate that anyway.

How to create a db model with table rows that have relationships to ever growing attributes?

For example, if I have a table that takes some type of 'item' whether it be products, animals, what have you, and I need to also store their attributes that can grow over time. What is the best way to model?
One way would be:
CREATE TABLE item
(
item_id int,
name varchar(255),
description varchar(255),
);
CREATE TABLE item_attr
(
item_attr_id int,
item_id int,
name varchar(255),
description varchar(255),
value varchar(255)
)
Now if I add an item to the items table, and this item gets 100 different attributes with name, description, any possible value (number, text, etc), then I would have 100 rows just for that one item in the item_attr table. Is that the best way to do it?
It depends whether the attributes are share between items. In that case you would create them in a separate table and create linktable between them
CREATE TABLE item
(
item_id int,
name varchar(255),
description varchar(255),
);
CREATE TABLE attr
(
attr_id int,
name varchar(255),
description varchar(255),
)
CREATE TABLE item_attr
(
item_attr_id int,
item_id int,
attr_id int,
value varchar(255)
)