#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
У меня есть эта таблица:
ID | Имя | Роль |
---|---|---|
1 | Том | Администратор |
2 | Том | Пользователь |
3 | Джон | Администратор |
Из этой таблицы мне нужно скопировать данные в две таблицы следующим образом:
Пользователь:
ID | Имя |
---|---|
1 | Том |
2 | Джон |
Роль пользователя:
Идентификатор пользователя | Идентификатор роли |
---|---|
1 | Администратор |
1 | Пользователь |
2 | Администратор |
Как я могу сделать это в хранимой процедуре?
Ответ №1:
Вы можете использовать запросы:
insert into user (name)
select distinct name
from following;
insert into userrole (userid, roleid)
select u.userid, f.roleid
from following f join
user u
on f.name = u.name;
Они могут быть включены в хранимую процедуру.
Ответ №2:
вы также можете попробовать добавить, обновить, удалить слиянием. Слияние использует составной индекс или первичный ключ для поиска совпадающих строк. Это способ etl для хранилища данных. возможно, вам придется отключить идентификатор для первичного ключа.
use MyDataDB
declare @Output as varchar(max)
declare @ColumnName as varchar(100)
declare @TableName as varchar(30)='your_table_name'
declare @UpdateStatement as varchar(max)=''
declare @InsertStatement as varchar(max)=''
declare @InsertStatement2 as varchar(max)=''
declare @DeleteStatement as varchar(max)=''
Declare @Join as varchar(max)
declare @JoinColumns Table(ColumnName varchar(50))
---- Add your primary Key here or composite index
Insert into @JoinColumns(ColumnName)
values('YourKeyID')
select @Join=
(select ' AND TARGET.' ColumnName '=SOURCE.' ColumnName from @JoinColumns for xml path(''))
select @Join=right(@Join,len(@Join)-5)
declare c1 cursor
for
SELECT
COLUMN_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = @TableName
open c1
fetch next from c1 into @ColumnName
set @Output=N'MERGE ReportData.dbo.' @TableName ' as TARGET USING ReportData.dbo.' @TableName '_Stage as SOURCE ON
(' @Join ') WHEN MATCHED THEN ';
set @UpdateStatement=N' UPDATE SET ';
set @InsertStatement =N' WHEN NOT MATCHED BY TARGET THEN INSERT(';
set @InsertStatement2=N' Values(';
set @DeleteStatement=N' WHEN NOT MATCHED BY SOURCE THEN DELETE';
while @@FETCH_STATUS=0
begin
if not exists(select '' from @JoinColumns where ColumnName=@ColumnName)
begin
if @UpdateStatement=N' UPDATE SET '
SET @UpdateStatement=@UpdateStatement 'TARGET.' @ColumnName '=' 'SOURCE.' @ColumnName
else
SET @UpdateStatement=@UpdateStatement ',TARGET.' @ColumnName '=' 'SOURCE.' @ColumnName
end
if @InsertStatement =N' WHEN NOT MATCHED BY TARGET THEN INSERT('
BEGIN
Set @InsertStatement=@InsertStatement @ColumnName
Set @InsertStatement2=@InsertStatement2 'SOURCE.' @ColumnName
END
ELSE
BEGIN
Set @InsertStatement=@InsertStatement ',' @ColumnName
Set @InsertStatement2=@InsertStatement2 ',SOURCE.' @ColumnName
END
fetch next from c1 into @ColumnName
end
close c1
deallocate c1
SET @Output=@Output @UpdateStatement
SET @Output=@Output @InsertStatement ') '
SET @Output=@Output @InsertStatement2 ') '
SET @Output=@Output @DeleteStatement ';'
select @Output