How to insert row in a table every time I insert a new row in the main table? - sql

I have a Vb.net app that is connected to an Access 2010* Database, I have a table with personal information of many students and another table with multiple true/false fields for every course the student has succed.
The structure is something like this
Table students
|Id_student | Name | Phone |
Table finishedCourses
| Id_stutent | chemistry | physics | maths |
How can I add a new row into finishedCourses table every time that I insert a new row into students table.
I don't know how add the rows with the same id in both tables.
I expect something like this
Table students
Id_student | Name | Phone
1234456 | abc | 12432534645
Table finishedCourses
Id_stutent | chemistry | physics | maths
1234456 | false | false | false
The default values for Courses are `False'. Initial status of each course is incomplete.

I tried to undestand what you want, you want to insert a initial values in finishedCourses when you insert a student information in table students, am I right?
I am not familiar with the Access database, I realized that the Access database may not have the trigger function, otherwise you can use the trigger to implement your requirement.
And in this problem, you can just write two insert SQLs to complete this with the same studentId, like below:
insert into students(id_101, 'Bob', '88089901');
insert into finishedCourses(id_101, false, false, false...);

If you are using SQL server then you can use trigger. The sample code is as below, I have no idea about MS-Access
CREATE TRIGGER trgAfterInsert ON [dbo].[students]
FOR INSERT
AS
DECLARE #Id_stutent int;
SELECT #Id_stutent=i.Id_student FROM inserted i;
INSERT INTO finishedCourses
(Id_stutent,chemistry,physics,maths)
VALUES(#Id_stutent ,false , false , false ,false );
GO

Related

Add a column with a default value to an existing table in postgresql

Question:
Is there a postgres query to add a new column to an existing table and to automatically populate that column for all rows of the table with a certain value, let's say "A1", just once, as the column is created, so that I can still set the DEFAULT value of the column to another value, let's say "B2"?
Just to be clear, I am looking for something like this:
Given my_table:
name | work
------------------------
bob | fireman
carl | teacher
alice | policeman
my query
ALTER TABLE my_table
ADD COLUMN description varchar(100)
DEFAULT "B2"
COMMAND_I_D_WISH_TO_KNOW "A1";
changes my_table into
name | work | description
-------------------------------------
bob | fireman | "A1"
carl | teacher | "A1"
alice | policeman | "A1"
so that if afterwards I run the query
INSERT INTO my_table(name, work)
VALUES karen, developer;
my_tables becomes
name | work | description
-------------------------------------
bob | fireman | "A1"
carl | teacher | "A1"
alice | policeman | "A1"
karen | developer | "B2"
Yes, you can do that by using two actions in one ALTER.
ALTER TABLE my_table
ADD COLUMN description varchar(100) DEFAULT 'A1',
ALTER COLUMN description SET DEFAULT 'B2';
I have verified that DROP DEFAULT doesn't work in the same command as the column was added in, unlike SET DEFAULT NULL. I don't think there is really a reason for it not to work, it just happens to do them in the wrong order for it to work, and no one has bothered to force it to do it in the right order. (Perhaps because no one even tested that exact thing and so realizes it is broken)
You can always just do them in different ALTER commands. If you are worried that someone might "see" the table in an in-between state, you can do both in a single transaction. Then the lock is not released in between so no one can see it. The real advantage of doing multiple actions in one command is that the table doesn't need to be rewritten multiple times. But here, it doesn't need to get rewritten at all anyway.
Referencing the most recent docs, this operation can be done using two statements.
Adds the column with the old default value
ALTER TABLE my_table ADD COLUMN description varchar(100) DEFAULT 'A1';
Modifies the column to use a different default value
ALTER TABLE my_table ALTER COLUMN description SET DEFAULT 'B2'
A full reproducible sample has been included below:
CREATE TABLE my_table (
"name" VARCHAR(5),
"work" VARCHAR(9)
);
INSERT INTO my_table
("name", "work")
VALUES
('bob', 'fireman'),
('carl', 'teacher'),
('alice', 'policeman');
Query #1
select * from my_table;
name
work
bob
fireman
carl
teacher
alice
policeman
Query #2
ALTER TABLE my_table
ADD COLUMN description varchar(100)
DEFAULT 'A1';
There are no results to be displayed.
Query #3
select * from my_table;
name
work
description
bob
fireman
A1
carl
teacher
A1
alice
policeman
A1
Query #4
ALTER TABLE my_table
ALTER COLUMN description SET DEFAULT 'B2';
There are no results to be displayed.
Query #5
INSERT INTO my_table("name", "work")
VALUES ('karen', 'developer');
There are no results to be displayed.
Query #6
select * from my_table;
name
work
description
bob
fireman
A1
carl
teacher
A1
alice
policeman
A1
karen
developer
B2
View working demo on DB Fiddle
Let me know if this works for you.

Get back the id of each insert in SQL Server

Let's say we want to insert two users and I want to know the userId of each record I inserted.
Example:
Db:
User.lookup database with these columns:
UserId(PK, identity) | Username
Setup, insert two users:
declare #users table (uniqueId INT, name nvarchar(100));
insert into #users (0, 'TestUser')--Two users with the same name, they'll get a different userid in the db
insert into #users (1, 'TestUser')--Uniqueid is just an autonumber I use to tell the difference between them.
Insert statement:
insert into user.lookup (userName)
output inserted.userid
select name from #users;
This will return two usersIds, example 1 & 2. But how do I know which of the two users got which userId?
I can differentiate them in code with their 'uniqueid' I pass but I don't know how to return it.
Don't just output the id. You can include other columns:
insert into user.lookup (userName)
output inserted.*
select name from #users;
Here is a db<>fiddle.
You can't correlate the inserted rows with the database-assigned IDs, at least not without inserting an alternate key as well. INSERT ... OUTPUT will not let you output a row that wasn't actually inserted, so the column that correlates the un-keyed rows with the new key values has to be actually inserted.
So the options are:
To use a SEQUENCE instead of IDENTITY and and either assign IDs to the table variable before insert, or assign IDs to the entities on the client, eg by calling sp_sequence_get_range.
Use MERGE instead of INSERT. This is what Entity Framework Core does. See eg The Case of Entity Framework Core’s Odd SQL
As Gordon explained, one can output more than 1 column.
But just to put my 2 cents in, such insert doesn't really need an intermediate table variable.
create table lookup (
lookupId int identity primary key,
userName nvarchar(100),
createdOn datetime2 not null
default sysdatetime()
)
GO
✓
insert into lookup (userName) values
('TestUser1')
,('TestUser2')
;
GO
2 rows affected
insert into lookup (userName)
output inserted.lookupId, inserted.userName
values
('Testuser3'),
('Testuser3')
GO
lookupId | userName
-------: | :--------
3 | Testuser3
4 | Testuser3
select lookupId, userName
--, convert(varchar,createdOn) as createdOn
from lookup
order by lookupId
GO
lookupId | userName
-------: | :--------
1 | TestUser1
2 | TestUser2
3 | Testuser3
4 | Testuser3
db<>fiddle here

How can I update the table in SQL?

I've created a table called Youtuber, the code is below:
create table Channel (
codChannel int primary key,
name varchar(50) not null,
age float not null,
subscribers int not null,
views int not null
)
In this table, there are 2 channels:
|codChannel | name | age | subscribers | views |
| 1 | PewDiePie | 28 | 58506205 | 16654168214 |
| 2 | Grandtour Games | 15 | 429 | 29463 |
So, I want to edit the age of "Grandtour Games" to "18". How can I do that with update?
Is my code right?
update age from Grandtour Games where age='18'
No, in update, you'll have to follow this sequence:
update tableName set columnWanted = 'newValue' where columnName = 'elementName'
In your code, put this:
update Channel set age=18 where name='Grandtour Games'
Comments below:
/* Channel is the name of the table you'll update
set is to assign a new value to the age, in your case
where name='Grandtour Games' is referencing that the name of the Channel you want to update, is Grandtour Games */
alter table changes the the schema (adding, updating, or removing columns or keys, that kind of thing).
Update table changes the data in the table without changing the schema.
So the two are really quite different.
Here is your answer -
-> ALTER is a DDL (Data Definition Language) statement
UPDATE is a DML (Data Manipulation Language) statement.
->ALTER is used to update the structure of the table (add/remove field/index etc).
Whereas UPDATE is used to update data.
Hope this helps!

SQL - keep values with UPDATE statement

I have a table "news" with 10 rows and cols (uid, id, registered_users, ....) Now i have users that can log in to my website (every registered user has a user id). The user can subscribe to a news on my website.
In SQL that means: I need to select the table "news" and the row with the uid (from the news) and insert the user id (from the current user) to the column "registered_users".
INSERT INTO news (registered_users)
VALUES (user_id)
The INSERT statement has NO WHERE clause so i need the UPDATE clause.
UPDATE news
SET registered_users=user_id
WHERE uid=post_news_uid
But if more than one users subscribe to the same news the old user id in "registered_users" is lost....
Is there a way to keep the current values after an sql UPDATE statement?
I use PHP (mysql). The goal is this:
table "news" row 5 (uid) column "registered_users" (22,33,45)
--- 3 users have subscribed to the news with the uid 5
table "news" row 7 (uid) column "registered_users" (21,39)
--- 2 users have subscribed to the news with the uid 7
It sounds like you are asking to insert a new user, to change a row in news from:
5 22,33
and then user 45 signs up, and you get:
5 22,33,45
If I don't understand, let me know. The rest of this solution is an excoriation of this approach.
This is a bad, bad, bad way to store data. Relational databases are designed around tables that have rows and columns. Lists should be represented as multiple rows in a table, and not as string concatenated values. This is all the worse, when you have an integer id and the data structure has to convert the integer to a string.
The right way is to introduce a table, say NewsUsers, such as:
create table NewsUsers (
NewsUserId int identity(1, 1) primary key,
NewsId int not null,
UserId int not null,
CreatedAt datetime default getdaete(),
CreatedBy varchar(255) default sysname
);
I showed this syntax using SQL Server. The column NewsUserId is an auto-incrementing primary key for this table. The columns NewsId is the news item (5 in your first example). The column UserId is the user id that signed up. The columns CreatedAt and CreatedBy are handy columns that I put in almost all my tables.
With this structure, you would handle your problem by doing:
insert into NewsUsers
select 5, <userid>;
You should create an additional table to map users to news they have registeres on
like:
create table user_news (user_id int, news_id int);
that looks like
----------------
| News | Users|
----------------
| 5 | 22 |
| 5 | 33 |
| 5 | 45 |
| 7 | 21 |
| ... | ... |
----------------
Then you can use multiple queries to first retrieve the news_id and the user_id and store them inside variables depending on what language you use and then insert them into the user_news.
The advantage is, that finding all users of a news is much faster, because you don't have to parse every single idstring "(22, 33, 45)"
It sounds like you want to INSERT with a SELECT statement - INSERT with SELECT
Example:
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_temp1.fld_order_id
FROM tbl_temp1
WHERE tbl_temp1.fld_order_id > 100;

MySQL: Multiple Inserts for a single column

I'm looking for a way to do multiple row inserts when I'm only inserting data for a single column.
Here is the example table:
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | tinyint(4) | NO | PRI | NULL | auto_increment |
| name | varchar(40) | NO | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
I want to be able to insert something like ('admin', 'author', 'mod', 'user', 'guest') into the name column for each row.
The MySQL documentation shows that multiple inserts should be in the format:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
However my statement ends up looking like this:
INSERT INTO User_Role(name) VALUES ('admin','author','mod','user','guest');
And I get the following:
ERROR 1136 (21S01): Column count doesn't match value count at row 1
Meaning that it thinks I'm trying to do a single row insert.
I'm not sure if I'm just missing something simple here, but I don't see anything in particular in the MySQL docs for this use case.
your syntax is a bit off. put parentheses around each data "set" (meaning a single value in this case) that you are trying to insert.
INSERT INTO User_Roll(name) VALUES ('admin'), ('author'), ('mod'), ('user'), ('guest');
I will advise you Don't put multiple values in a column.
make a new table:
INSERT INTO table_name (id, name) VALUES (1, 'name1'), (1, 'name2'), (1, 'name3'), (1, 'name4');