Лучший способ скопировать дату из одной таблицы в некоторые другие

#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