Sql - create entry in table A for every entry in table B - sql

I have table Users model with id. Now i create table(model) Settings which should store settings for every User form Users table. How can i create entry in table Settings for every exist User from Users table?
Column Users:
id ;some value ; someothervalue;
Column Settings:
id ; user_id ; message_1 ; message_2
I want to create entry in the table Settings for every User. Right now every new User have before_create filter but old users havent got entry in Settings table.

Insert TableSettings(list of ColNames ...)
Select [list of colnames ...]
From TableUsers
Just make sure that the list of colNames in tableSettings match (in the number of columns and datatype) the list of columns in tableUsers.
to start with just the UserId and message_1
Insert tableSettings(userID, message_1)
Select id, 'A message with someotherValue:' + someothervalue
from tableUsers

Related

Insert into new table with userId column for all users from existing users table

I have user_settings table with two columns, userId and value which is currently empty but have another users table and now I need to add migration with query which should popuplate user_settings table for all users with some default value for value column.
I began with INSERT INTO "user_settings" ("userId", "value") VALUES ($1, $2) and got stuck. How to loop all id's from users table and fill this user_settings table with some default value...
There is really no need to 'loop' through the rows in users, as you can easily achieve this using an INSERT INTO SELECT statement (https://www.w3schools.com/sql/sql_insert_into_select.asp) like this:
SET #default = 'your_settings';
INSERT INTO `user_settings` (
`userId`,
`value`
)
SELECT
id,
#default
FROM
users
Suppose you are using a DBMS that supports triggers, you could also add a trigger to insert default settings upon inserting new records in users.
In MySQL it might look something like this:
DELIMITER $$
CREATE TRIGGER after_user_insert
AFTER INSERT
ON
users
FOR EACH ROW
BEGIN
INSERT INTO user_settings (
userId,
value
)
VALUES (
NEW.id,
'your_settings'
);
END$$
DELIMITER ;
(Assuming the primary key on users table is called id.)
Assuming some syntax elements here because you didn't say which database system you are using.
INSERT INTO "user_settings" ("userId", "value")
SELECT DISTINCT "userId", 'defaultvalue'
FROM "users"
To learn more, read training materials such as those found at:
https://www.w3schools.com/sql/default.asp

Oracle : Create session sequence?

I have a table as follows
The table contains my application users and stores their clients. The column User Client ID refers to a foreign key linked to a different table that stores the clients details.
I need another column (User Client Counter) which is a just a counter of the clients of each user. I need it to start from 1 and goes up for each individual application user.
For the moment I'm populating this by counting the number of clients for each user + 1 before inserting a new row in the table :
select count(*) + 1 into MyVariable from Mytable where UserClientId = Something
Then I use MyVariable in the column User Client Counter
This methods works quite well, but in case the user is connected from two different sessions, the query may produce a wrong number of counts... in addition to that the performance may be bad in case of big tables...
Is there anyway better way to replace such process by using sequences ?
I've been looking to session sequences but there are reset after the end of each session.
(This column is a business need and cannot be replaced by something like rownumber in restitution queries. Since every client has to keep always the same identifier for the application user)
Thank you in advance.
Cheers,
I think you can just create a unique index on the app user and the running number:
create unique index idx on mytable (app_user_id, num);
And then insert with max + 1:
insert into mytable (app_user_id, client_id, num)
values
(
:app_user_id,
:client_id,
coalesce((select max(num) + 1 from mytable where app_user_id = :app_user_id), 1)
);
For this sort of requirement to be safe you will need to be able to lock rows at the right level so that you don't have two sessions that think the they are allowed to use the same value. The impact of this is that while one session is inserting a row for the 'Company X' user, another session will wait for the first user to commit if they're also trying to insert a row for 'Company X'.
This is super easy when you just have a table that stores information at the right level.
You can have a table of your users with a counter column which starts at 0.
MY_APPLICATION_USER CLIENT_COUNTER
-------------------------------------------------- --------------
Company X 1
Company Y 3
Company Z 1
As you insert rows into your main table, you update this table first setting the client_counter to be client_counter + 1 (you do this as one insert statement, no risky select then update!), then you return the updated value into your value for the client_id. This can all be done with a simple trigger.
create or replace trigger app_clients_ins
before insert
on app_clients
for each row
declare
begin
update app_users
set client_counter = client_counter + 1
where my_application_user = :new.my_application_user
return client_counter into :new.user_client_number;
end;
/
Of course, like any sequence if you delete a row it's not going to allow your next insert to fill that gap.
(db<>fiddle https://dbfiddle.uk/?rdbms=oracle_18&fiddle=7f1b4f4b6316d5983b921cae7b89317a )
if you want to have unique values to be inserted and there are chances that multiple users can insert rows into the same table at the same time then it is better to user Oracle Sequence.
CREATE SEQUENCE id_seq INCREMENT BY 1;
INSERT INTO Mytable(id) VALUES (id_seq.nextval);
In you case I think you want different sequence created for each Customer, How many different Customers you have, if you have in 100's then i don't think create sequence will work as you may have to create as many sequence .

How to display the list of books of a user in php code

I am a beginner in programming.
I want to create a site in which I would like to display the list of books of a user that he has previously added. here is the schema of the code.
table book;
id ,name,detail ,urlimage.
table users;
id,name,email,password.
table add_book;
uses_id INT ,book_id INT , key primary (users_id ,book_id ).
I have three tables in my database; the book table, the users table and the add_book table. their structures is given in the above question add_book.users_id and add_book.book_id are foreign keys. I would like to make sure that when a user adds a book to his list, an entry is created in the add_book table with the request. ('INSERT INTO kal224_sory.add_book (users_id, book_id) VALUES (: users,: book)'); $ sql-> execute (['users' => $ users_id, 'book' => $ book_id]); .It works well where there is problem, I try to send in json the fields of the table book that correspond to book_id which have the same entries users_id where(add_book.users_id = $ users_id) of the table add_book. the code I tried is;
You need to SELECT the data from the add_book table that belongs to a particular uses_id (sp.)
SELECT * FROM add_book WHERE uses_id = 1 -- change '1' to whatever user's ID you'd like to view data for

Automatically create record when another is created

I have two tables in my database: Users, Roles and Membership. The Membership table assigns users to specific Roles.
How could I automatically create the Membership record for anytime a new record is inserted in Users.
Example: When a user is created and assigned an ID number (# 562), The database would automatically add them to the Membership table with a specific role ID.
How could I do this?
Write an AFTER INSERT TRIGGER on Users TABLE, that will INSERT the new Row in the Membership table.
http://msdn.microsoft.com/en-us/magazine/cc164047.aspx
Assuming you have a Default RoleID for your new Membership row, when a new User is inserted in Users table, something like this should work.
CREATE TRIGGER TRI_USERS_INSERT on Users
AFTER INSERT
AS
SET NOCOUNT ON
-- If you have a Default RoleID, select that into a variable and use it in the INSERT below.
-- For this example, I am using just the number 1
-- Also assumes that the ID for Memberships table is AUTO GENERATED, so it's not in INSERT list.
INSERT INTO Memberships (UserID, RoleID)
SELECT ID, 1 FROM INSERTED
GO

How to insert non duplicate names in SQL

I want to add a new user in my table users
users
------
ID NAME
1 abc
2 cde
how could I use the syntax 'no exists' in this case if for example someone by mistake insert another user with the name 'abc' I dont want to enter with the same name user again.
You just need to make the column as UNIQUE
ALTER IGNORE TABLE users ADD UNIQUE (NAME);
This will prevent to have duplicates in the column NAME