2013-04-21 4 views
1

У меня есть таблица 'user' с userid как PK. Мне нужно добавить это как FK в 2 столбца из нескольких существующих таблиц. Пока я обновляю каждую таблицу. путь.добавить внешний ключ к нескольким существующим таблицам

alter table table1 
add foreign key(createdby) references users(id) 
go 
alter table table1 
add foreign key(createdby) references users(id) 
go 

Есть ли более простой способ обновить все таблицы за один раз. Спасибо.

+0

Если вы используете приложение, как ColdFusion, .net и т.д., и эти приложения имеют необходимые permisions, вы могли бы петли через список tablenames. –

+0

Привет. Я использую sql server 2008 r2. Я могу получить имена tbl: "select table_name from information_schema.columns где column_name = 'createdby' и table_catalog = 'dbtables' .... но я не знаю, hw продолжить дальше – Ruby

+0

Нет, нет более простого способа сделать это - если вы хотите добавить внешние ключи в 10 таблиц, вам нужно написать 10 команд 'ALTER TABLE'. –

ответ

1

maby что-то вроде этого сделало бы трюк!

DECLARE @TableName AS NVARCHAR(128) 
DECLARE @Schema AS NVARCHAR(128) 
DECLARE @Modify AS INTEGER 
DECLARE @Created AS INTEGER 
DECLARE @sql1 as nvarchar(max) 
DECLARE @sql2 as nvarchar(max) 
DECLARE curs CURSOR FOR 
SELECT 
A.[name], 
S.[name] as schemaname, 
(SELECT 1 FROM sys.all_objects innero 
where innero.[name] = 'FK_ModifiedBy' 
AND innero.parent_object_id = a.[object_id]) as ModifiedBy, 
(SELECT 1 FROM sys.all_objects innero 
where innero.[name] = 'FK_CreatedBy' 
AND innero.parent_object_id = a.[object_id]) as CreatedBy 
FROM 
    sys.all_objects A 
INNER JOIN 
sys.all_columns O ON 
A.[object_id] = O.[object_id] 
INNER JOIN 
SYS.schemas S ON 
A.[schema_id] = S.[schema_id] 
WHERE 
O.name = 'ModifiedBy' 
OPEN curs 
FETCH NEXT FROM curs 
INTO @TableName, @Schema, @Modify, @Created 
WHILE @@FETCH_STATUS = 0 
BEGIN 
IF @Modify IS NULL 
BEGIN 
set @sql1 = N'ALTER TABLE ' + @Schema + '.' + @TableName 
+ ' ADD CONSTRAINT FK_ModifiedBy FOREIGN KEY (ModifiedBy) 
REFERENCES ' + @Schema + '.Users(userid)' 
exec SP_EXECUTESQL @sql1 
END 
IF @Created IS NULL 
BEGIN 
set @sql2 = N'ALTER TABLE ' + @Schema + '.' + @TableName 
+ ' ADD CONSTRAINT FK_CreatedBy FOREIGN KEY (createdby) 
REFERENCES ' + @Schema + '.Users(userid)' 
exec SP_EXECUTESQL @sql2 
END 
FETCH NEXT FROM curs 
INTO @TableName, @Schema, @Modify, @Created 
END 
CLOSE curs 
DEALLOCATE curs 



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

+0

У всех нас есть свои собственные предпочтения, и мой заключается в том, что устранение горизонтальной прокрутки гораздо важнее, чем отступы. –

+0

@ Christer. @ Dan. Большое спасибо. Это сработало – Ruby

1

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

DECLARE SQLStr SHORTSTRING(1000); 
DECLARE NoDefaultsCursor CURSOR FOR 
    SELECT 'ALTER TABLE "' || TABLE_NAME || 
      '" ALTER COLUMN "' || FIELD_NAME || '" SET DEFAULT ' || 
    CASE FIELD_TYPE_SQL 
     WHEN 'INTEGER' THEN '0' 
     WHEN 'BOOLEAN' THEN 'FALSE' 
     WHEN 'SHORTSTRING' THEN '''''' 
     WHEN 'CHARACTER VARYING' THEN '''''' 
    END || ';' AS AddDefaultSQL 
    FROM #FIELDS WHERE NOT FIELD_HASDEFAULT 
    AND FIELD_TYPE_SQL IN 
     ('INTEGER','BOOLEAN','SHORTSTRING','CHARACTER VARYING'); 
OPEN NoDefaultsCursor; 
FETCH NEXT FROM NoDefaultsCursor INTO SQLStr; 
WHILE @@FETCH_STATUS = 0 DO 
    Execute Immediate SQLStr; 
    FETCH NEXT FROM NoDefaultsCursor INTO SQLStr; 
END WHILE; 
CLOSE NoDefaultsCursor; 
0

Я также попробовал компактную версию christer.This работал тоже. Мысль может быть полезным для кого-то еще

declare @tblname nvarchar(50),@sql1 nvarchar(max),@sql2 nvarchar(max) 
declare curs cursor for 
select TABLE_NAME from INFORMATION_SCHEMA.COLUMNS where COLUMN_NAME ='createdby' 
open curs 
fetch next from curs into @tblname 
while @@FETCH_STATUS=0 
    begin 
    set @sql1='alter table dbo.'+ @tblname+ 
    ' add foreign key(createdby) references users(id)' 
    exec sp_executesql @sql1 
    set @sql2='alter table dbo.'[email protected]+ 
    ' add foreign key(modifiedby) references users(id)' 
    exec sp_executesql @sql2 
    fetch next from curs into @tblname 
    end 
close curs 
deallocate curs 
+0

Это будет работать, но вы не можете запустить его много раз, верите, что вы получите ошибки. Кроме того, если у вас есть множественная схема, вам также придется включить это. Хорошо, что это сработало для вас! :) –

+0

да, вы правы – Ruby

Смежные вопросы