Delete rows from 2 tables using a single query - sql

I have the following database-schema:
I have the following example data:
CREATE TABLE computermapping (
ComputerMappingID int NOT NULL,
PrinterGUID char(36) NOT NULL,
ComputerGUID char(36) NOT NULL
);
INSERT INTO computermapping (ComputerMappingID, PrinterGUID, ComputerGUID) VALUES
(1, 'PRT01', 'Computer1'),
(2, 'PRT02', 'Computer1'),
(3, 'PRT01', 'Computer2'),
(4, 'PRT02', 'Computer2'),
(5, 'PRT03', 'Computer2'),
(6, 'PRT01', 'Computer3');
CREATE TABLE computerdefaultprinter (
ComputerGUID char(36) NOT NULL,
PrinterGUID char(36) NOT NULL
);
INSERT INTO computerdefaultprinter (ComputerGUID, PrinterGUID) VALUES
('Computer2', 'PRT01'),
('Computer1', 'PRT02');
Remark: Originally the tables are full of GUIDs, but I replaced them by names just for better readability.
I have also created an SQL-Fiddle with some example-data: Link
.
Taking the example data, I want to remove the printer "PRT01" from computer "Computer2".
I need to delete the appropriate row in the table computermapping and I need to delete the appropriate row in the table computerdefaultprinter. I want to delete the mentioned data in BOTH tables using ONE SINGLE statement.
According to my program-code I need to target the data by using NOT IN().
Till now I successfully used 2 statements joined/glued together by ";":
DELETE FROM computermapping WHERE PrinterGUID = 'PRT01' AND ComputerGUID NOT IN ('Computer1','Computer3');
DELETE FROM computerdefaultprinter WHERE PrinterGUID = 'PRT01' AND ComputerGUID NOT IN ('Computer1','Computer3')
This was working fine using MySQL, but it is not working with Microsoft SQL-Server. Yes, it does using the SQL Server Management Studio, but not programmatically. (count field incorrect or syntax error)
I am looking for a different approach for this task.
I did a research and it was mentioned, that it should be possible to delete the rows in both tables using "INNER JOIN", but I wasn't able to get it working and I am looking for help.
Thank you

You can add a foreign key with ON DELETE CASCADE.
For example:
CREATE TABLE computermapping (
ComputerMappingID int NOT NULL,
PrinterGUID char(36) NOT NULL,
ComputerGUID char(36) NOT NULL,
primary key (ComputerGUID, PrinterGUID)
);
INSERT INTO computermapping (ComputerMappingID, PrinterGUID, ComputerGUID) VALUES
(1, 'PRT01', 'Computer1'),
(2, 'PRT02', 'Computer1'),
(3, 'PRT01', 'Computer2'),
(4, 'PRT02', 'Computer2'),
(5, 'PRT03', 'Computer2'),
(6, 'PRT01', 'Computer3');
CREATE TABLE computerdefaultprinter (
ComputerGUID char(36) NOT NULL,
PrinterGUID char(36) NOT NULL,
foreign key (ComputerGUID, PrinterGUID)
references computermapping (ComputerGUID, PrinterGUID)
on delete cascade
);
INSERT INTO computerdefaultprinter (ComputerGUID, PrinterGUID) VALUES
('Computer2', 'PRT01'),
('Computer1', 'PRT02');
delete from computermapping
where PrinterGUID = 'PRT01' and ComputerGUID = 'Computer2';
The DELETE deletes a row in computermapping and all related rows from computerdefaultprinter as well.
See running example at SQL Fiddle.

Related

writing trigger containing multiple conditions

So I have a table trans which has two columns tx_type and ref_nbr
and I want to create a trigger such that the trigger ensures the following condition
in the trans table.
The following two conditions should be ensured:
if tx_type = D or W then ref_nbr should match the branch_nbr in branch table
if tx_type= B , P or R then ref_nbr should match mer_nbr in mer table
Triggers are not intended for keeping consistency in database relations. Use foreign keys for that. So make a table trans not with one column ref_nbr but use 2 columns - one for each relation (foreign key). Additionaly you can create check constraint for making sure that correct column is filled for given tx_type.
If you try to use triggers, you will have problems with concurrent transactions changing related tables like deleting your ref_nbr.
Example definitions for mer, branch and trans tables with some sample inserts:
create table branch(
branch_nbr number generated by default on null as identity start with 3 primary key,
branch_name varchar2(100) not null
);
create table mer (
mer_nbr number generated by default on null as identity start with 2 primary key,
mer_name varchar2(100) not null
);
create table trans (
id number generated by default on null as identity primary key,
tx_type varchar2(1) not null,
ref_branch_nbr number,
ref_mer_nbr number,
constraint ck_tx_type check (tx_type in ('D', 'W', 'B', 'P', 'R')),
constraint ck_correct_ref_for_tx_type
check (
(tx_type in ('D', 'W') and ref_branch_nbr is not NULL and ref_mer_nbr is NULL)
or (tx_type in ('B', 'P', 'R') and ref_branch_nbr is NULL and ref_mer_nbr is not NULL)
),
constraint fk_trans_ref_branch_nbr
foreign key (ref_branch_nbr)
references branch(branch_nbr),
constraint fk_trans_ref_mer_nbr
foreign key (ref_mer_nbr)
references mer(mer_nbr)
);
insert into branch(branch_nbr, branch_name) values(1, 'Master');
insert into branch(branch_nbr, branch_name) values(2, 'Test');
insert into mer(mer_nbr, mer_name) values(1, 'Test to Master');
commit;
-- working:
insert into trans(tx_type, ref_mer_nbr) values('P', 1);
insert into trans(tx_type, ref_branch_nbr) values('D', 1);
-- not working - non existing parent:
insert into trans(tx_type, ref_mer_nbr) values('P', 999);
insert into trans(tx_type, ref_branch_nbr) values('D', 999);
-- not working - wrong tx_type or wrong ref column:
insert into trans(tx_type, ref_mer_nbr) values('D', 1);
insert into trans(tx_type, ref_branch_nbr) values('P', 1);
insert into trans(tx_type, ref_branch_nbr, ref_mer_nbr ) values('P', 1, 1);
-- not working - cant insert without tx_type
insert into trans(ref_mer_nbr, ref_branch_nbr) values(1, 1);

How to insert multiple values in one column of type number in oracle?

I have table like
CREATE TABLE TEMP_TABLE
(
temp_acct number(10) NOT NULL,
temp_code varchar2(250),
temp_bal number(10,2),
CONSTRAINT TEMP_TABLE_PK PRIMARY KEY(temp_acct)
);
Is it possible to insert multiple values into column temp_bal in one row something like below,I know the syntax is incorrect but is there any way?
INTO TEMP_TABLE (temp_acct, temp_code, temp_bal)
VALUES (1000, 'code100, code101, code102, code103', '1000.00,2000.00,3000.00');

Why do I receive error 1241 when trying to Create and Insert data into a new table (on phpMyAdmin)?

I am trying to create a new table and insert values into it however I keep receiving "#1241 - Operand should contain 1 column(s)".
Please could someone help to identify what is wrong with my code as I am unsure what this error is referencing?
The code I am inserting into the phpMyAdmin database under the SQL tab. I have tried to remove the auto increment attributes and have tried looking at other examples to check my syntax, but I can't spot the issue. Some guidance on this would be greatly appreciated.
The code I entered begins like this:
# AppSoft Project - Greg Roberts
DROP table if exists Department;
DROP table if exists Role;
DROP table if exists User;
DROP table if exists Appraisal;
DROP table if exists Question;
DROP table if exists Answer;
CREATE table Department(
DeptID int NOT NULL AUTO_INCREMENT,
DeptName varchar(30) NOT NULL,
primary key (DeptID));
INSERT into Department values(
(00, 'SuperAdmin'),
(01, 'Support Staff'),
(02, 'Teaching Staff'),
(03, 'SLT'));
CREATE table Role(
RoleID int NOT NULL AUTO_INCREMENT,
RoleTitle varchar(30) NOT NULL,
primary key (RoleID));
INSERT into Role values(
(00, 'SuperAdmin'),
(01, 'Office Administrator'),
(02, 'Teaching Partner'),
(03, 'Mid Day Supervisor'),
(04, 'Cooks'),
(05, 'Cleaners'),
(06, 'Maintenance'),
(07, 'Teacher'),
(08, 'Department Head'),
(09, 'SENCO'),
(10, 'Head Teacher'),
(11, 'Executive Head'));
Error Code that Occurs
You dont need to insert primary keys, if they are set to auto_increment.
DeptID int NOT NULL AUTO_INCREMENT
Just insert the department name, there are no additional braces required for Values.
INSERT into Department( DeptName) values
('SuperAdmin'),
('Support Staff'),
('Teaching Staff'),
('SLT');
You would need to do the same for Role table as well.
Also if you try to insert 0 into the primary key, it will actually insert 1 you can read about it in the Standard Docs
you seem to be getting the error because your first record inserts 1 into the table and then your second record tries to insert 1 again in the primary key column

How to fix an SQL design

I'm doing the study of a medical software. This software asks the patients questions about their symptoms and from them it can determine the possible pathologies. My study involves comparing the symptoms and pathologies found by the software with those from the hospital.
In order to make my work easier, I decided to enter the data in a database made with javadb on netbeans 8.2.
But it seems like that I did something wrong since my statement doesn't work.
I thank you in advance anybody who would take the time to help me.
SQL design:
Create table Patients(
nip varchar(32) primary key,
sexe varchar(8) not null,
age int not null,
dateArrivee timestamp not null,
constraint ck_sexe check(sexe='Male' or sexe='Female'),
constraint ck_age check (age>=0)
);
Create table Symptoms(
symptomID int primary key generated always as identity (start with 1,
increment by 1),
nip varchar(32) not null,
symptom varchar(64),
origin varchar(16) not null,
foreign key (nip) references Patients(nip),
constraint ck_origin check (origin='SOFTWARE' or origin='HOSPITAL')
);
Create table Pathologies(
pathologyID int primary key generated always as identity (start with 1,
increment by 1),
nip varchar(32) not null,
pathology varchar(64),
origin varchar(16) not null,
foreign key (nip) references Patients(nip),
constraint ck_origin check (origin='SOFTWARE' or origin='HOSPITAL')
);
Values entered:
Insert into Patients values ('001','Male', 25, '2019-05-27 14:00:00');
Insert into Patients values ('002', 'Female', 30, '2019-05-26 15:00:00');
Insert into Symptoms values (, '001', 'Headache', 'SOFTWARE');
Insert into Pathologies values (,'001', 'Fever', 'SOFTWARE');
Insert into Symptoms values (,'001', 'Stomache', 'HOSTPITAL');
Insert into Pathologies values (, '001', 'Gastro-enteritis', 'HOSPITAL');
Insert into Symptoms values(,'002', 'Headache', 'SOFTWARE');
Insert into Pathologies values (,'002', 'Unknow', 'SOFTWARE');
SQL statement:
Select *
from (Patients inner join
Symptoms
on Patients.nip = Symptoms.nip
) inner join
Pathologies
on Symptoms.nip = Pathologies.nip
where Symptoms.origin = 'MEDVIR' and
Pathologies.origin = 'MEDVIR';
So sorry I forgot to put the errors I'm getting.
SQL design:
First I have an error concerning the auto_incrementation, even thought this was the good method. It says that the syntax is incorrect near the 'generated'.
Values entered:
Here I have an error concerning the a wrong syntax near the coma (',').
SQL statement:
Lastly I have an error saying that the object 'Patients' is unavaible.
If I am not wrong, you are trying to fetch entries where 'Origin' = 'MEDVIR'
Although, none of your insert statements have Origin as 'MEDVIR'
Please check below,
Select *
from (Patients inner join
Symptoms
on Patients.nip = Symptoms.nip
) inner join
Pathologies
on Symptoms.nip = Pathologies.nip
where Symptoms.origin IN ('SOFTWARE', 'HOSPITAL') and
Pathologies.origin IN ('SOFTWARE', 'HOSPITAL');
Also, some of your INSERT statement has an extra comma before the values, which would cause a syntax error.

How should I handle multiple foreign keys that all point to the same column in another table?

So let's say I have these two tables...
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='UnitsDef' AND xtype='U')
CREATE TABLE UnitsDef
(
UnitsID INTEGER PRIMARY KEY,
UnitsName NVARCHAR(32) NOT NULL,
UnitsDisplay NVARCHAR(8) NOT NULL
);
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='Dimensions' AND xtype='U')
CREATE TABLE Dimensions
(
DimID INTEGER PRIMARY KEY IDENTITY(0,1),
DimX FLOAT,
DimXUnitsID INTEGER DEFAULT 0,
DimY FLOAT,
DimYUnitsID INTEGER DEFAULT 0,
DimZ FLOAT,
DimZUnitsID INTEGER DEFAULT 0,
FOREIGN KEY (DimXUnitsID) REFERENCES UnitsDef(UnitsID),
FOREIGN KEY (DimYUnitsID) REFERENCES UnitsDef(UnitsID),
FOREIGN KEY (DimZUnitsID) REFERENCES UnitsDef(UnitsID)
);
I'll insert data into the first table similar to this...
INSERT INTO UnitsDef (UnitsID, UnitsName, UnitsDisplay) VALUES (0, 'inch', 'in.');
INSERT INTO UnitsDef (UnitsID, UnitsName, UnitsDisplay) VALUES (1, 'millimeter', 'mm');
INSERT INTO UnitsDef (UnitsID, UnitsName, UnitsDisplay) VALUES (2, 'degree', '°');
Am I going about this the right way? This is a simplified version of the problem, but I need to know which unit each measurement is given in. Is there a better design practice for this type of situation?
How would I handle the ON DELETE and ON UPDATE for these foreign keys? If I try to cascade deletes and updates, SQL Server would not be so happy about that.
Your method is pretty good. I would make the suggestion right off that UnitsId be an identity column, so it gets incremented. Your inserts would then be:
INSERT INTO UnitsDef (UnitsName, UnitsDisplay) VALUES ('inch', 'in.');
INSERT INTO UnitsDef (UnitsName, UnitsDisplay) VALUES ('millimeter', 'mm');
INSERT INTO UnitsDef (UnitsName, UnitsDisplay) VALUES ('degree', '°');
You should also make the string columns unique in UnitsDef and give them case-sensitive collations. After all, Ml and ml are two different things ("M" is mega and "m" is milli).
You might also want to combine the units and values into a single type. This has positives and negatives. For me it adds overhead, but it can help if you want to support a fuller algebra of types.