Есть ли способ автоматически добавить новую строку в соединительную таблицу в sql?

У меня есть две таблицы, tbl_Interview и tbl_JobSeeker, отношение между ними - многие ко многим, правила нормализации требуют, чтобы я создал новую таблицу, которую я назвал tbl_Interview_JobSeeker с первичными ключами двух других таблиц, мой вопрос: если таблица tbl_Interview_JobSeeker является существует ли в любом случае соединительная таблица, когда я создаю новую строку в таблице tbl_Interview, чтобы автоматически создать новую строку и в соединительной таблице?


person Mr.Toxy    schedule 18.06.2016    source источник
comment
Вы можете создать триггер, который обновляет соединительную таблицу после вставки в другую таблицу. Какую версию SQL вы используете?   -  person Tim Biegeleisen    schedule 18.06.2016
comment
Я использую SQL Express 2014. Мне также нужно создать электронный триггер для удаления правильно?   -  person Mr.Toxy    schedule 18.06.2016
comment
Нет. SQL Server использует каскадное удаление, поэтому очистка может не вызвать особых проблем.   -  person Tim Biegeleisen    schedule 18.06.2016
comment
хм, просто подытожу. Мне нужно создать триггер для добавления новой строки в соединительную таблицу, а для удаления я это программно правильно делаю?   -  person Mr.Toxy    schedule 18.06.2016
comment
Вы также можете использовать только два отдельных оператора вставки. Это действительно зависит от ваших конкретных потребностей.   -  person Tim Biegeleisen    schedule 18.06.2016
comment
Да, я пытался сделать вещи более автономными. У меня есть еще один вопрос, который вы, возможно, знаете. Я буду использовать электронную почту в качестве имени пользователя, и кто-то предположил, что тип данных имени пользователя должен быть uniqueidentifier правильно ли это предположение?   -  person Mr.Toxy    schedule 18.06.2016
comment
Я бы использовал varchar для электронной почты, но включил столбец id, который уникален для всех пользователей.   -  person Tim Biegeleisen    schedule 18.06.2016
comment
Все мои столбцы имеют идентификатор :), поэтому единственный способ проверить, что имя пользователя уже существует, - это запросить всю базу данных?   -  person Mr.Toxy    schedule 18.06.2016
comment
Да, так работают базы данных. Вы можете добавить индекс в таблицу имен пользователей, чтобы сделать ее быстрее.   -  person Tim Biegeleisen    schedule 18.06.2016
comment
по индексу вы имеете в виду хранить количество, скажем, пользователей в таблице? что именно вы подразумеваете под индексом?   -  person Mr.Toxy    schedule 18.06.2016
comment
Почему? Для какого JobSeeker будет новая строка в tbl_Interview_JobSeeker? Все они?   -  person Rhys Jones    schedule 18.06.2016
comment
@RhysJones новая строка добавляется в tbl_Interview_JobSeeker только тогда, когда новая строка также добавляется в tbl_Interview . Итак, допустим, что интервью было создано с пользователем 1 и идентификатором интервью 2, в tbl_Interview_JobSeeker должна быть добавлена ​​строка с UserID = 1 и InterviewID = 2, и это происходит каждый раз, когда в таблицу интервью добавляется новая строка.   -  person Mr.Toxy    schedule 18.06.2016
comment
новые значения будут представлять собой InterviewID, который является целым числом и ссылается на InterviewID в tbl_Interview, а также UserID, который также является целым числом и ссылается на таблицу UserID. Это был ваш вопрос?   -  person Mr.Toxy    schedule 18.06.2016
comment
Если на собеседовании есть только один соискатель, то в соединительной таблице нет необходимости. Является ли первичный ключ JobSeeker UserID?   -  person Rhys Jones    schedule 18.06.2016
comment
Я бы создал хранимую процедуру insert, которая выполняет обе вставки. Таким образом, вам нужно будет сделать только один вызов, и вам не придется совершать какие-то беспорядочные триггерные действия.   -  person jkdba    schedule 18.06.2016
comment
@RhysJones В интервью есть несколько соискателей, а соискатели проходят несколько собеседований, поэтому появилась новая соединительная таблица. Первичный ключ в таблице соискателей — UserID да   -  person Mr.Toxy    schedule 18.06.2016
comment
@jkdba это на самом деле довольно хорошая идея, и создайте еще один процесс для удаления   -  person Mr.Toxy    schedule 18.06.2016
comment
Обычный многие ко многим тогда. В этом случае INSERT для tbl_Interview не включает никаких сведений о JobSeeker (UserID), поэтому он не может создать строку в соединительной таблице.   -  person Rhys Jones    schedule 18.06.2016
comment
prntscr.com/bhypt8 см. это. может это поможет лучше понять   -  person Mr.Toxy    schedule 18.06.2016
comment
@RhysJones, почему он не может создать новую строку в таблице соединений? В таблице собеседований у меня нет поля для соискателя. пожалуйста, смотрите ссылку в комментарии выше :)   -  person Mr.Toxy    schedule 18.06.2016
comment
Я использую слово INSERT как оператор SQL. Если вы хотите, чтобы «действие» приложения по созданию новой строки в tbl_Interview также создавало новую строку в tbl_Interview_JobSeeker, вы можете это сделать, но вам нужно управлять им на уровне приложения, что может быть хранимой процедурой, как предлагает @jkdba, но это не может быть триггером в таблице tbl_Interview.   -  person Rhys Jones    schedule 18.06.2016
comment
@RhysJones о, хорошо, спасибо :) Я думаю, что возьму подход к процедуре, кажется простым, и это хороший подход, имо   -  person Mr.Toxy    schedule 18.06.2016
comment
процедура будет примерно такой: prntscr.com/bhyz9r   -  person Mr.Toxy    schedule 18.06.2016
comment
Я не знаю почему, но он не распознает имя таблицы или поля   -  person Mr.Toxy    schedule 18.06.2016


Ответы (1)


Я думаю, вы хотели бы использовать хранимую процедуру для создания отношений между JobSeeker и Interview, которые являются независимыми объектами и живут сами по себе. Эта связь «многие ко многим» очень распространена в реляционной реальности. Ниже приведен пример решения отношений в реляционной базе данных. Хотя он использует концепцию Человека и Курса.

Создайте таблицы

create table Person (
    PersonId int identity(1, 1)
        primary key clustered,
    FirstName varchar(128),
    LastName varchar(128))

create table Course (
    CourseId int identity(1, 1)
        primary key clustered,
    CourseName varchar(128) unique);

create table PersonCourse (
    PersonId int not null
        references Person(PersonId),
    CourseId int not null
        references Course(CourseId),
    primary key clustered (PersonId, CourseId));
go

Создайте хранимые процедуры, используемые для операций CRUD

Это лишь некоторые примеры. Многие из этих типов процедур более сложны для защиты от неполных, неточных и/или недействительных данных.

Кроме того, само собой разумеется, что есть много альтернатив этому подходу и много споров о том, к чему относятся эти типы проверок. Просто знайте, что это один подход.

create proc dbo.CreatePerson
    @FirstName varchar(128),
    @LastName varchar(128),
    @PersonId int = null output
as begin try

    set nocount on;

    insert Person (FirstName, LastName)
        values (@FirstName, @LastName);

    set @PersonId = scope_identity();

end try
begin catch
    throw;
end catch
go

create proc dbo.CreateCourse
    @CourseName varchar(128),
    @CourseId int = null output
as begin try

    set nocount on;

    insert Course(CourseName)
        values (@CourseName);

    set @CourseId = scope_identity();

end try
begin catch
    throw;
end catch
go

create proc dbo.AddCourse
    @PersonId int,
    @CourseId int
as begin try

    set nocount on;

    if not exists (
        select * 
        from Person
        where PersonId = @PersonId)
            throw 50000, 'Person does not exist.', 1;

    if not exists (
        select *
        from Course
        where CourseId = @CourseId)
            throw 50001, 'Course does not exist.', 1;

    insert PersonCourse (PersonId, CourseId)
        values (@PersonId, @CourseId);

end try
begin catch
    throw;
end catch
go

Создайте образцы данных

insert Person (FirstName, LastName)
    values
        ('Bruce', 'Wayne'),
        ('Clark', 'Kent'),
        ('Flash', 'Gordon');

insert Course (CourseName)
    values
        ('The History of Spandex'),
        ('Super Hero Physics'),
        ('Rocket Ships and the Stuff of Science Fiction');
go

Добавить несколько курсов

exec AddCourse 1, 1; -- Bruce wants to take The History of Spandex
exec AddCourse 2, 2; -- Clark wants to take Super Hero Physics
exec AddCourse 3, 1; -- Flash wants to take The History of Spandex
exec AddCourse 3, 3; -- Flash wants to also take Rocket Ships and the Stuff of Science Fiction

Запросить данные

select
    pc.PersonId,
    p.FirstName,
    p.LastName,
    c.CourseId,
    c.CourseName
from PersonCourse pc
join Person p
    on pc.PersonId = p.PersonId
join Course c
    on pc.CourseId = c.CourseId;

И результаты

PersonId    FirstName  LastName   CourseId    CourseName
----------- ---------- ---------- ----------- -----------------------------------------------
1           Bruce      Wayne      1           The History of Spandex
2           Clark      Kent       2           Super Hero Physics
3           Flash      Gordon     1           The History of Spandex
3           Flash      Gordon     3           Rocket Ships and the Stuff of Science Fiction
person Yobik    schedule 18.06.2016