2017-05-14 1 views
3

이것은 StackOverflow에 대한 첫 번째 게시물입니다. 수백 년 동안 SQL과 PowerShell에 대한 수백 가지 질문에 대답하기 위해이 놀라운 리소스를 여러 해 동안 사용해 왔습니다. 그러나이 질문은 저에게 여러 날 동안 저돌적이었습니다.SQL Update 여러 테이블 조인 (필드가있는 경우)

SQL Server 2014 SP2를 사용하고 있는데 다른 데이터베이스에서 DATABASE1, FIELD1, FIELD2, FIELD3에 대한 업데이트를 수행하려고합니다.

FIELD1은 다른 여러 데이터베이스 중 하나에 존재할 수 있습니다. FIELD1이 모든 데이터베이스에 존재하지 않을 수 있습니다 - 문제가있는 곳입니다.

Database Design Link

나는 다음 (익명으로) 쿼리를 가지고 제대로 동작 표시 : 나는 입력란 8 말을 얻을 때까지 DATABASE2, DATABASE3 또는에서 DATABASE1에는 있지만 같은

EXEC sp_MSforeachdb 'IF ''?'' IN (''DATABASE2'',''DATABASE3'',''DATABASE4'') 
BEGIN 
    UPDATE DATABASE1.PARAMETER 
    SET B.[VALUE] = A.[FIELD1] 
    FROM DATABASE1.TABLE1 B 
    INNER JOIN ?.dbo.[TABLE2] A 
    ON A.JOINVALUE = B.JOINVALUE 
    WHERE B.COLUMN2 = ''SOMETHING'' 
    AND COLUMN3= ''PF.T.FIELD1'' 
END ;' 

데이터베이스 4. 정말 투쟁에 시작했던 곳

IF EXISTS (SELECT COLUMN1 FROM Database2.Table2 WHERE Column1='Field8') 
    EXEC ....... 

하지만 그건 : 다음 다음 오류 얻을 : 내 구글과 StackOverflow의 검색에서

Msg 207, Level 16, State 1, Line 30  
Invalid column name 'FIELD8'. 

를, 내가 (처음)를 사용하려고했습니다 .

희망은 이상적입니다. 팁이나 도움을 주시면 감사하겠습니다.

N.B. 데이터베이스 1에는 업데이트가 필요한 약 3,000 개의 필드가 있습니다. 지금까지 모든 내 UPDATE 문을 동적으로 작성했습니다.

+0

당신 그것을 만들고 업데이트해야합니까? 또는 필드가있는 경우에만 업데이트하면됩니까? – gofr1

+0

안녕하세요 @ gofr1 - 존재하지 않으면 업데이트를 건너 뜁니다. 필드가 "DATABASE2", "DATABASE3"또는 "DATABASE4"인 경우 "DATABASE1"만 업데이트하면됩니다. – Simon

답변

1

먼저 sp_MSforeachdb은 신뢰할 수 없습니다. 작업 대안을 보려면 여기를 확인하십시오

if exists (
    select 1 
    from sys.columns c 
    where c.name = 'pilots_id' /* column name */ 
    and c.object_id = object_id(N'pilots') /* table name */ 
    ) 
    begin 
    select 'Pilots_Id exists' /* do stuff */ 
    end 

rextester 데모 : http://rextester.com/UUXCB18567

1

열이과 같이 sys.columns를 사용하여 주어진 테이블에 존재하는 경우 Making a more reliable and flexible sp_MSforeachdb - Aaron Bertrand

둘째, 당신은 확인 시스템 뷰를 사용할 수 있습니다 시스템 테이블의 열과 테이블을 검색하는 저장된 proc을 만들 수 있습니다.

ALTER PROCEDURE dbo.check_table_exists 
    -- Add the parameters for the stored procedure here 
     @table_name nvarchar(255), 
     @column_name nvarchar(255) 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- Insert statements for procedure here 
    DECLARE @SQLString nvarchar(max), 
      @ParmDefinition nvarchar(500) = N'@table_name nvarchar(255), @column_name nvarchar(255)'; 

    IF OBJECT_ID(N'tempdb..#check_column_exists') is not null DROP TABLE #check_column_exists 
    CREATE TABLE #check_column_exists (
     db nvarchar(500) NULL, 
     column_exists bit NULL 
    ) 

    SELECT @SQLString = 
    (
     SELECT N'USE '+QUOTENAME([name]) +'; '+ 
     'INSERT INTO #check_column_exists '+ 
     'SELECT '''+[name]+''' as [db], '+ 
     '  COUNT(*) as column_exists ' + 
     'FROM sys.tables t ' + 
     'INNER JOIN sys.columns c ' + 
     ' ON t.[object_id] = c.[object_id] ' + 
     'WHERE t.[name] = @table_name and c.[name] = @column_name; ' 
     FROM sys.databases 
     WHERE [name] NOT IN (
      'msdb', 
      'model', 
      'tempdb', 
      'master' 
     ) 
     FOR XML PATH('') 
    ) + 'SELECT [db] FROM #check_column_exists WHERE column_exists = 1; DROP TABLE #check_column_exists;' 

    EXEC sp_executesql @SQLString, @ParmDefinition, @table_name = @table_name, @column_name = @column_name 
END 
GO 

chan 그것은 단지 열을 검색하고 데이터베이스와 테이블 이름 등을 출력합니다.

출력은 : 그 후

db 
----------- 
DATABASE1 
DATABASE4 
... 
etc 

당신이 테이블에이를 작성하고 동적 SQL 업데이트 쿼리에 사용할 수 : 필드에 어떤 DB에 존재하지 않는 경우 .. 그래서

DECLARE @table_name nvarchar(255) = 'SomeTable', 
     @column_name nvarchar(255) = 'SomeField' 

DECLARE @results TABLE (
    db nvarchar(500) 
) 

INSERT INTO @results 
EXEC dbo.check_table_exists @table_name, @column_name 

--...Here goes building of dynamic SQL query to update data