Как автоматически добавлять значения в одну таблицу при выполнении условия - PullRequest
0 голосов
/ 27 апреля 2018

Итак, вот условие.

У меня есть User_tbl, код которого следующий:

CREATE TABLE Users_tbl (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    username TEXT,
    password TEXT,
    user_type INT
);

user_type - это либо 0,1, либо 2. Если это 0, то это игрок, 1 - для тренера, 2 - для аудитории.

Теперь я хочу создать новую таблицу, в которой есть списки coach. Чья схема будет

CREATE TABLE coach_tbl(
coach_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
username TEXT,
password TEXT
)

и что мне нужно, так это то, что, когда запись, помещаемая в Users_tbl, имеет user_type = 1, она должна инициировать еще один запрос, который создаст запись в coach_tbl и заполнит столбцы. Это должно происходить динамически.

1 Ответ

0 голосов
/ 28 апреля 2018

Следующий TRIGGER выполнит то, что вы хотите: -

CREATE TRIGGER setup_coach 
AFTER INSERT ON Users_tbl
WHEN new.user_type = 1
    BEGIN 
        INSERT INTO coach_tbl (username, password) VALUES(new.username,new.password);
    END
;

Для проверки вышеперечисленного использовалось следующее: -

DROP TABLE IF EXISTS Users_tbl;
CREATE TABLE IF NOT EXISTS Users_tbl (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    username TEXT,
    password TEXT,
    user_type INT
);
DROP TABLE IF EXISTS coach_tbl;
CREATE TABLE IF NOT EXISTS coach_tbl(
coach_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
username TEXT,
password TEXT
);

CREATE TRIGGER setup_coach 
AFTER INSERT ON Users_tbl
WHEN new.user_type = 1
    BEGIN 
        INSERT INTO coach_tbl (username, password) VALUES(new.username,new.password);
    END
;
INSERT INTO Users_tbl (username, password,user_type) 
VALUES 
    ('Fred','fred1234',0),
    ('Bert','bert1234',1),
    ('Harold','harold1234',0),
    ('Alan','alan1234',1);

Результат: -

enter image description here

Дополнительный (иначе почему не выше)

Хранение одинаковых значений. их дублирование противоречит нормализации и может привести к проблемам. например если (используя вышеизложенное) имя или пароль "Bert" изменились, вам придется изменить его в двух местах. В настоящее время нет необходимости дублировать эти данные, поскольку они будут легко доступны

Например, если вы хотите перечислить тренеров, которых вы можете использовать: -

SELECT username FROM coach_tbl;

Использование следующего, однако, возвращает точно то же самое, но без дополнительной таблицы: -

SELECT username FROM Users_tbl WHERE user_type = 1;

Предположим, у вас была конкретная информация о тренере, например, например, сколько раз вы тренировались, тогда у вас может быть дополнительная таблица, например: -

CREATE TABLE IF NOT EXISTS coaching_information
    (
    user_id_reference INTEGER REFERENCES Users_tbl(id),
    number_of_times_coaching INTEGER DEFAULT 0
    )
;

Наряду с TRIGGER для автоматического добавления информации о коучинге по умолчанию: -

CREATE TRIGGER autoadd_coaching_information_entry
AFTER INSERT ON Users_tbl 
WHEN new.user_type = 1
BEGIN 
    INSERT INTO coaching_information
        (user_id_reference)
        VALUES (new.id)
        ;
END
;
  • Примечание! нет необходимости устанавливать столбец number_of_times_coaching, так как по умолчанию он равен 0.

Предполагая, что все СТОЛЫ были опустошены, затем используйте (снова): -

INSERT INTO Users_tbl (username, password,user_type) 
VALUES 
    ('Fred','fred1234',0),
    ('Bert','bert1234',1),
    ('Harold','harold1234',0),
    ('Alan','alan1234',1);

Результат: -

enter image description here

  • 2 относится к Берту, 4 к Алану

Затем вы могли бы перечислить всех тренеров, которые не тренировали (выбранных из-за лени отсутствия необходимости обновлять информацию о коучинге): -

SELECT 'Coach '||username||' is up for a coaching experience.' AS coaching_needed 
FROM coaching_information 
JOIN Users_tbl ON Users_tbl.id = coaching_information.user_id_reference
WHERE coaching_information.number_of_times_coaching < 1 

Результат будет: -

enter image description here

Скажите, что Берт сменил имя на Чарльза, например используя UPDATE Users_tbl SET username = 'Charles' WHERE username = 'Bert';

Тогда только с 1 изменением результаты из вышеупомянутого запроса будут: -

enter image description here

Полный SQL, использованный для тестирования выше, был: -

DROP TABLE IF EXISTS coach_tbl;
DROP TABLE IF EXISTS Users_tbl;
CREATE TABLE IF NOT EXISTS Users_tbl (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    username TEXT,
    password TEXT,
    user_type INT
);

DROP TRIGGER IF EXISTS setup_coach; -- get rid of defunct TRIGGER
CREATE TABLE IF NOT EXISTS coaching_information
    (
    user_id_reference INTEGER REFERENCES Users_tbl(id) ON DELETE CASCADE,
        -- Note ON DELETE CASCADE will automatically delete a coach should 
        -- the coach's User_tbl entry be deleted i.e. the deletion is propoagted
        -- to the children of the parent.
        -- (could also use ON UPDATE CASCADE but unlikely to change the underlying id)
    number_of_times_coaching INTEGER DEFAULT 0
    )
;

DROP TRIGGER IF EXISTS autoadd_coaching_information_entry;
CREATE TRIGGER autoadd_coaching_information_entry
AFTER INSERT ON Users_tbl 
WHEN new.user_type = 1
BEGIN 
    INSERT INTO coaching_information
        (user_id_reference)
        VALUES (new.id)
        ;
END

;
INSERT INTO Users_tbl (username, password,user_type) 
VALUES 
    ('Fred','fred1234',0),
    ('Bert','bert1234',1),
    ('Harold','harold1234',0),
    ('Alan','alan1234',1)
;
--
-- Note! oncommmenting this will change Bert's name to Charles
--UPDATE Users_tbl SET username = 'Charles' WHERE username = 'Bert';
--
SELECT 'Coach '||username||' is up for a coaching experience.' AS coaching_needed 
FROM coaching_information 
JOIN Users_tbl ON Users_tbl.id = coaching_information.user_id_reference
WHERE coaching_information.number_of_times_coaching < 1 
...