MS-SQL Linked Server 사용자 매핑 설정하는 방법 ( 접속자별 권한 설정 )

DataBase/MS-SQL|2018.04.24 11:05

MS-SQL Linked Server  사용자 매핑 설정하는 방법 ( 접속자별 권한 설정 )



개요 


사용자 매핑을 사용하지 않고 단순 원격서버에 대한 로그인정보로 Linked Server를 연결하여 보안 셋팅 없이 경우 모든 사용자가 Linked Server에 대한 권한을 동일하게 갖게 되므로 보안 이슈가 발생할 수 있다.



▼ 흔히 인터넷상에서 알려주는 Linked Server 연결 방법.




문제점 확인 및 문제 발생 상황


위와 같은 방법으로 Linked Server를 설정 할 경우 모든 사용자가 같은 계정으로 원격 서버에 접속하기 때문에 여러 권한 관련 보안 이슈가 발생할 수 있게 된다.


DBA가 없는 규모가 작거나 사수가 없는 경우 혹은 별도 교육을 통하지 않는 경우 사실상 세부 옵션을 알아서 사용하기가 어렵기 때문에 위의 방법으로 연결해서 사용하던 때가 있었으나 외부에 뷰테이블 형태로 제공되는 서비스가 생기면서 해당 이슈가 발생되었다.



Linked Server 권한 문제 해결방법


해결방법은 이미 위에 옵션 화면에 노출되어있는데 

로컬 서버 로그인과 원격 서버 로그인 매핑 옵션을 이용해야한다.




이말은 SQL Server에 로그인된 사용자 별로 Linked Server 연결 아이디를 다르게 하고 매핑에 등록되지 않은 사용자의 경우 아래에 옵션에 해당하는 연결을 한다는 의미이다.

  • 연결안함.
  • 보안컨텍스트 없이 연결
  • 로그인의 현재 보안 컨텍스트를 사용하여 연결
  • 다음 보안 컨텍스트를 사용하여 연결




로컬 로그인 사용자를 선택하고 원격 사용자와 암호를 입력한다.

로컬 로그인의 경우 등록된 계정을 사용하기 때문에 콤보박스에서 선택하면 됨.




입력된 결과이며 여러개 중복 등록이 가능하므로 사용자 별로 Linked Server 의 접속 계정을 설정하여 권한 및 보안 설정이 가능하다.

그리고 그외의 접속에 대해서는 연결을 하지 않거나 하는 등의 설정이 아래 옵션에서 처리가 가능하니 참고.





상세한 내용은 아래 링크를..


https://docs.microsoft.com/ko-kr/previous-versions/sql/sql-server-2008-r2/ms188477(v%3dsql.105)

댓글(0)

[MS-SQL] 테이블 정의서 생성 쿼리

DataBase/MS-SQL|2017.09.08 11:34

MS-SQL 테이블 정의서 HTML 생성 쿼리





초기 출처는 기억이 잘 안나네요.

몇년전쯤 인터넷에서 찾았던 것 같습니다.
(문제될 경우 연락주시면 삭제하겠습니다.)

이후 이것저것 수정해서 사용해왔고 현 시점에서 아래 최종본으로 공유합니다.

2000 버전과 2005버전으로 구분되어 있으나 크게 다른바가 없어서 문제 없이 작동합니다.




Declare @i Int, @maxi Int
Declare @j Int, @maxj Int
Declare @sr int
Declare @Output nvarchar(4000)
--Declare @tmpOutput varchar(max)
Declare @SqlVersion varchar(5)
Declare @last varchar(155), @current varchar(255), @typ varchar(255), @description nvarchar(4000)

create Table #Tables  (id int identity(1, 1), Object_id int, Name varchar(155), Type varchar(20), [description] nvarchar(4000))
create Table #Columns (id int identity(1,1), Name varchar(155), Type Varchar(155), Nullable varchar(2), [description] nvarchar(4000))
create Table #Fk(id int identity(1,1), Name varchar(155), col Varchar(155), refObj varchar(155), refCol varchar(155))
create Table #Constraint(id int identity(1,1), Name varchar(155), col Varchar(155), definition varchar(1000))
create Table #Indexes(id int identity(1,1), Name varchar(155), Type Varchar(25), cols varchar(1000))

 If (substring(@@VERSION, 1, 25 ) = 'Microsoft SQL Server 2005')
 set @SqlVersion = '2005'
else if (substring(@@VERSION, 1, 26 ) = 'Microsoft SQL Server  2000')
 set @SqlVersion = '2000'
else
 set @SqlVersion = '2005'


Print '<head>'
Print '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'
Print '<title>::' + DB_name() + '::</title>'
Print '<style>'

Print 'body {'
Print 'font-family:verdana;'
Print 'font-size:9pt;'
Print '}'

Print 'td {'
Print 'font-family:verdana;'
Print 'font-size:9pt;'
Print '}'

Print 'th {'
Print 'font-family:verdana;'
Print 'font-size:9pt;'
Print 'background:#d3d3d3;'
Print '}'
Print 'table'
Print '{'
Print 'background:#d3d3d3;'
Print '}'
Print 'tr'
Print '{'
Print 'background:#ffffff;'
Print '}'
Print ' </style>'
Print '</head>'
Print '<body>'

set nocount on
 if @SqlVersion = '2000'
  begin
  insert into #Tables (Object_id, Name, Type, [description])
   --FOR 2000
   select object_id(table_name),  '[' + table_schema + '].[' + table_name + ']',
   case when table_type = 'BASE TABLE'then 'Table'   else 'View' end,
   cast(p.value as nvarchar(4000))
   from information_schema.tables t
   left outer join sysproperties p on p.id = object_id(t.table_name) and smallid = 0 and p.name = 'MS_Description'
   order by table_type, table_schema, table_name
  end
 else if @SqlVersion = '2005'
  begin
  insert into #Tables (Object_id, Name, Type, [description])
  --FOR 2005
  Select o.object_id,  '[' + s.name + '].[' + o.name + ']',
    case when type = 'V' then 'View' when type = 'U' then 'Table' end,
    cast(p.value as nvarchar(4000))
    from sys.objects o
     left outer join sys.schemas s on s.schema_id = o.schema_id
     left outer join sys.extended_properties p on p.major_id = o.object_id and minor_id = 0 and p.name = 'MS_Description'
    where type in ('U', 'V')
    order by type, s.name, o.name
  end
Set @maxi = @@rowcount
set @i = 1

print '<table border="0" cellspacing="0" cellpadding="0" width="550px" align="center"><tr><td colspan="3" style="height:50;font-size:14pt;text-align:center;"><a name="index"></a><b>Index</b></td></tr></table>'
print '<table border="0" cellspacing="1" cellpadding="0" width="550px" align="center"><tr><th>Sr</th><th>Object</th><th>Type</th></tr>'
While(@i <= @maxi)
begin
 select @Output =  '<tr><td align="center">' + Cast((@i) as varchar) + '</td><td><a href="#' + Type + ':' + name + '">' + name + '</a></td><td>' + Type + '</td></tr>'
   from #Tables where id = @i

 print @Output
 set @i = @i + 1
end
print '</table>'

set @i = 1
While(@i <= @maxi)
begin
 --table header
 select @Output =  '<tr><th align="left"><a name="' + Type + ':' + name + '"></a><b>' + Type + ':' + name + '</b></th></tr>',  @description = [description]
   from #Tables where id = @i

 print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td align="right"><a href="#index">Index</a></td></tr>'
 print @Output
 print '</table>'
 print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Description</b></td></tr><tr><td>' + isnull(@description, '') + '</td></tr></table>'

 --table columns
 truncate table #Columns
 if @SqlVersion = '2000'
  begin
  insert into #Columns  (Name, Type, Nullable, [description])
  --FOR 2000
  Select c.name,
     type_name(xtype) + (
     case when (type_name(xtype) = 'varchar' or type_name(xtype) = 'nvarchar' or type_name(xtype) ='char' or type_name(xtype) ='nchar')
      then '(' + cast(length as varchar) + ')'
      when type_name(xtype) = 'decimal'
       then '(' + cast(prec as varchar) + ',' + cast(scale as varchar)   + ')'
     else ''
     end  
     ),
     case when isnullable = 1 then 'Y' else 'N'end,
     cast(p.value as nvarchar(4000))
    from syscolumns c
     inner join #Tables t on t.object_id = c.id
     left outer join sysproperties p on p.id = c.id and p.smallid = c.colid and p.name = 'MS_Description'
    where t.id = @i
    order by c.colorder
  end
 else if @SqlVersion = '2005'
  begin
  insert into #Columns  (Name, Type, Nullable, [description])
  --FOR 2005
  Select c.name,
     type_name(user_type_id) + (
     case when (type_name(user_type_id) = 'varchar' or type_name(user_type_id) = 'nvarchar' or type_name(user_type_id) ='char' or type_name(user_type_id) ='nchar')
      then '(' + cast(max_length as varchar) + ')'
      when type_name(user_type_id) = 'decimal'
       then '(' + cast([precision] as varchar) + ',' + cast(scale as varchar)   + ')'
     else ''
     end  
     ),
     case when is_nullable = 1 then 'Y' else 'N'end,
     cast(p.value as nvarchar(4000))
  from sys.columns c
    inner join #Tables t on t.object_id = c.object_id
    left outer join sys.extended_properties p on p.major_id = c.object_id and p.minor_id  = c.column_id and p.name = 'MS_Description'
  where t.id = @i
  order by c.column_id
  end
 Set @maxj =   @@rowcount
 set @j = 1

 print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Table Columns</b></td></tr></table>'
 print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Datatype</th><th>Nullable</th><th>Description</th></tr>'

 While(@j <= @maxj)
 begin
  select @Output = '<tr><td width="20px" align="center">' + Cast((@j) as varchar) + '</td><td width="150px">' + isnull(name,'')  + '</td><td width="150px">' +  upper(isnull(Type,'')) + '</td><td width="50px" align="center">' + isnull(Nullable,'N') + '</td><td>' + isnull([description],'') + '</td></tr>'
   from #Columns  where id = @j

  print  @Output
  Set @j = @j + 1;
 end

 print '</table>'

 --reference key
 truncate table #FK
 if @SqlVersion = '2000'
  begin
  insert into #FK  (Name, col, refObj, refCol)
 --  FOR 2000
  select object_name(constid), s.name,  object_name(rkeyid) ,  s1.name
    from sysforeignkeys f
     inner join sysobjects o on o.id = f.constid
     inner join syscolumns s on s.id = f.fkeyid and s.colorder = f.fkey
     inner join syscolumns s1 on s1.id = f.rkeyid and s1.colorder = f.rkey
     inner join #Tables t on t.object_id = f.fkeyid
    where t.id = @i
    order by 1
  end
 else if @SqlVersion = '2005'
  begin
  insert into #FK  (Name, col, refObj, refCol)
--  FOR 2005
  select f.name, COL_NAME (fc.parent_object_id, fc.parent_column_id) , object_name(fc.referenced_object_id) , COL_NAME (fc.referenced_object_id, fc.referenced_column_id)   
  from sys.foreign_keys f
   inner  join  sys.foreign_key_columns  fc  on f.object_id = fc.constraint_object_id
   inner join #Tables t on t.object_id = f.parent_object_id
  where t.id = @i
  order by f.name
  end

 Set @maxj =   @@rowcount
 set @j = 1
 if (@maxj >0)
 begin

  print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Refrence Keys</b></td></tr></table>'
  print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Column</th><th>Reference To</th></tr>'

  While(@j <= @maxj)
  begin

   select @Output = '<tr><td width="20px" align="center">' + Cast((@j) as varchar) + '</td><td width="150px">' + isnull(name,'')  + '</td><td width="150px">' +  isnull(col,'') + '</td><td>[' + isnull(refObj,'N') + '].[' +  isnull(refCol,'N') + ']</td></tr>'
    from #FK  where id = @j

   print @Output
   Set @j = @j + 1;
  end

  print '</table>'
 end

 --Default Constraints
 truncate table #Constraint
 if @SqlVersion = '2000'
  begin
  insert into #Constraint  (Name, col, definition)
  select object_name(c.constid), col_name(c.id, c.colid), s.text
    from sysconstraints c
     inner join #Tables t on t.object_id = c.id
     left outer join syscomments s on s.id = c.constid
    where t.id = @i
    and
    convert(varchar,+ (c.status & 1)/1)
    + convert(varchar,(c.status & 2)/2)
    + convert(varchar,(c.status & 4)/4)
    + convert(varchar,(c.status & 8)/8)
    + convert(varchar,(c.status & 16)/16)
    + convert(varchar,(c.status & 32)/32)
    + convert(varchar,(c.status & 64)/64)
    + convert(varchar,(c.status & 128)/128) = '10101000'
  end
 else if @SqlVersion = '2005'
  begin
  insert into #Constraint  (Name, col, definition)
  select c.name,  col_name(parent_object_id, parent_column_id), c.definition
  from sys.default_constraints c
   inner join #Tables t on t.object_id = c.parent_object_id
  where t.id = @i
  order by c.name
  end
 Set @maxj =   @@rowcount
 set @j = 1
 if (@maxj >0)
 begin

  print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Default Constraints</b></td></tr></table>'
  print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Column</th><th>Value</th></tr>'

  While(@j <= @maxj)
  begin

   select @Output = '<tr><td width="20px" align="center">' + Cast((@j) as varchar) + '</td><td width="250px">' + isnull(name,'')  + '</td><td width="150px">' +  isnull(col,'') + '</td><td>' +  isnull(definition,'') + '</td></tr>'
    from #Constraint  where id = @j

   print @Output
   Set @j = @j + 1;
  end

 print '</table>'
 end


 --Check  Constraints
 truncate table #Constraint
 if @SqlVersion = '2000'
  begin
  insert into #Constraint  (Name, col, definition)
   select object_name(c.constid), col_name(c.id, c.colid), s.text
    from sysconstraints c
     inner join #Tables t on t.object_id = c.id
     left outer join syscomments s on s.id = c.constid
    where t.id = @i
    and ( convert(varchar,+ (c.status & 1)/1)
     + convert(varchar,(c.status & 2)/2)
     + convert(varchar,(c.status & 4)/4)
     + convert(varchar,(c.status & 8)/8)
     + convert(varchar,(c.status & 16)/16)
     + convert(varchar,(c.status & 32)/32)
     + convert(varchar,(c.status & 64)/64)
     + convert(varchar,(c.status & 128)/128) = '00101000'
    or convert(varchar,+ (c.status & 1)/1)
     + convert(varchar,(c.status & 2)/2)
     + convert(varchar,(c.status & 4)/4)
     + convert(varchar,(c.status & 8)/8)
     + convert(varchar,(c.status & 16)/16)
     + convert(varchar,(c.status & 32)/32)
     + convert(varchar,(c.status & 64)/64)
     + convert(varchar,(c.status & 128)/128) = '00100100')

  end
 else if @SqlVersion = '2005'
  begin
  insert into #Constraint  (Name, col, definition)
   select c.name,  col_name(parent_object_id, parent_column_id), definition
   from sys.check_constraints c
    inner join #Tables t on t.object_id = c.parent_object_id
   where t.id = @i
   order by c.name
  end
 Set @maxj =   @@rowcount

 set @j = 1
 if (@maxj >0)
 begin

  print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Check  Constraints</b></td></tr></table>'
  print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Column</th><th>Definition</th></tr>'

  While(@j <= @maxj)
  begin

   select @Output = '<tr><td width="20px" align="center">' + Cast((@j) as varchar) + '</td><td width="250px">' + isnull(name,'')  + '</td><td width="150px">' +  isnull(col,'') + '</td><td>' +  isnull(definition,'') + '</td></tr>'
    from #Constraint  where id = @j
   print @Output
   Set @j = @j + 1;
  end

  print '</table>'
 end


 --Triggers
 truncate table #Constraint
 if @SqlVersion = '2000'
  begin
  insert into #Constraint  (Name)
   select tr.name
   FROM sysobjects tr
    inner join #Tables t on t.object_id = tr.parent_obj
   where t.id = @i and tr.type = 'TR'
   order by tr.name
  end
 else if @SqlVersion = '2005'
  begin
  insert into #Constraint  (Name)
   SELECT tr.name
   FROM sys.triggers tr
    inner join #Tables t on t.object_id = tr.parent_id
   where t.id = @i
   order by tr.name
  end
 Set @maxj =   @@rowcount

 set @j = 1
 if (@maxj >0)
 begin

  print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Triggers</b></td></tr></table>'
  print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Description</th></tr>'

  While(@j <= @maxj)
  begin
   select @Output = '<tr><td width="20px" align="center">' + Cast((@j) as varchar) + '</td><td width="150px">' + isnull(name,'')  + '</td><td></td></tr>'
    from #Constraint  where id = @j
   print @Output
   Set @j = @j + 1;
  end

  print '</table>'
 end

 --Indexes
 truncate table #Indexes
 if @SqlVersion = '2000'
  begin
  insert into #Indexes  (Name, type, cols)
   select i.name, case when i.indid = 0 then 'Heap' when i.indid = 1 then 'Clustered' else 'Nonclustered' end , c.name
   from sysindexes i
    inner join sysindexkeys k  on k.indid = i.indid  and k.id = i.id
    inner join syscolumns c on c.id = k.id and c.colorder = k.colid
    inner join #Tables t on t.object_id = i.id
   where t.id = @i and i.name not like '_WA%'
   order by i.name, i.keycnt
  end
 else if @SqlVersion = '2005'
  begin
  insert into #Indexes  (Name, type, cols)
   select i.name, case when i.type = 0 then 'Heap' when i.type = 1 then 'Clustered' else 'Nonclustered' end,  col_name(i.object_id, c.column_id)
    from sys.indexes i
     inner join sys.index_columns c on i.index_id = c.index_id and c.object_id = i.object_id
     inner join #Tables t on t.object_id = i.object_id
    where t.id = @i
    order by i.name, c.column_id
  end

 Set @maxj =   @@rowcount

 set @j = 1
 set @sr = 1
 if (@maxj >0)
 begin

  print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Indexes</b></td></tr></table>'
  print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Type</th><th>Columns</th></tr>'
  set @Output = ''
  set @last = ''
  set @current = ''
  While(@j <= @maxj)
  begin
   select @current = isnull(name,'') from #Indexes  where id = @j

   if @last <> @current  and @last <> ''
    begin
    print '<tr><td width="20px" align="center">' + Cast((@sr) as varchar) + '</td><td width="150px">' + @last + '</td><td width="150px">' + @typ + '</td><td>' + @Output  + '</td></tr>'
    set @Output  = ''
    set @sr = @sr + 1
    end


   select @Output = @Output + cols + '' , @typ = type
     from #Indexes  where id = @j

   set @last = @current
   Set @j = @j + 1;
  end
  if @Output <> ''
    begin
    print '<tr><td width="20px" align="center">' + Cast((@sr) as varchar) + '</td><td width="150px">' + @last + '</td><td width="150px">' + @typ + '</td><td>' + @Output  + '</td></tr>'
    end

  print '</table>'
 end

    Set @i = @i + 1;
 --Print @Output
end


Print '</body>'
Print '</html>'

drop table #Tables
drop table #Columns
drop table #FK
drop table #Constraint
drop table #Indexes
set nocount off



댓글(0)

[MS-SQL] 두 데이터베이스의 테이블 및 컬럼 비교하는 쿼리

DataBase/MS-SQL|2017.09.07 15:04


MS-SQL 두 데이터베이스 

테이블 및 컬럼 비교 하는 쿼리


A 와 B 두 데이터베이스의 테이블 및 컬럼속성(데이터 타입 , 길이)를 비교하는 쿼리 입니다.

두 데이터 베이스간의 데이터 동기화를 위해 비교하기 위해 사용.


그때 그때 코딩하거나 찾아보기 귀찮기 때문에

블로그에 포스팅 해둠!

 

select A.table_name, A.column_name, A.column_default, A.data_type, A.character_maximum_length,
B.column_name, B.column_default, B.data_type, B.character_maximum_length
from information_schema.columns A left outer join restotalPackage.information_schema.columns B
on A.table_name = B.table_name and A.column_name = B.column_name
where (B.column_name is null or B.column_name = ''
or A.column_default <> B.column_default
or A.data_type <> B.data_type ) 
-- and (A.table_name like '%테이블 이름%' or A.table_name = '테이블 이름')
order by A.table_name, A.column_name


댓글(0)

테이블 설명 추가/수정 프로시저 쿼리 (sp_addextendedproperty , sp_updateextendedproperty )

DataBase/MS-SQL|2017.06.16 13:08

테이블 설명 추가/수정 프로시저 쿼리
 

EXEC sp_addextendedproperty 'MS_Description', '등록할 설명', 'user', dbo, 'table','테이블명' EXEC sp_updateextendedproperty 'MS_Description', '수정할 설명', 'user', dbo, 'table','테이블명'


댓글(0)