2017-12-18 3 views
1

SQL Server 사용자를 LinkedServers를 통해 집계하려고하지만 쿼리에서 데이터베이스 이름을 선택할 수 없습니다. 내가 사용하려고했는데 db_name() as ''Database'' 내 선택 진술에 있지만 현재 데이터베이스 컨텍스트를 사용하고 내가 선택한 데이터베이스가 아닙니다. 데이터베이스 컨텍스트가 실제로 변경되지 않도록 "정규화 된"데이터베이스 이름을 사용 중이기 때문에 이러한 상황이 발생한다는 것을 알았습니다. 또한 select 문에서 커서 값을 가져올 수 없습니다.동적 SQL 내에서 Select 문에서 커서 값을 사용하는 방법 (SQL Server)

내가 선택한 데이터베이스의 데이터베이스 이름을 얻는 방법에 대한 아이디어가있는 사람이 있습니까? 변수 값을 사용하는

DECLARE @DatabaseName VARCHAR(30) 

DECLARE c1 CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY FOR 
SELECT 
    Name 
FROM 
    [LinkedServer].master.sys.databases 
WHERE 
    Name NOT IN  (
        'master', 
        'model', 
        'tempdb', 
        'msdb', 
        'distribution', 
        ) 


OPEN c1 

FETCH NEXT FROM c1 
INTO @DatabaseName 

WHILE @@FETCH_STATUS = 0 
BEGIN 

EXEC (
' 
--INSERT INTO [Gather_Privileged_DBUsers_Sox] 
SELECT distinct (dp.name) as ''DatabaseUser'', 
     s.name as ''ServerName'', 
     db_name() as ''Database'', 
     getdate() as ''date'' 
FROM [LinkedServer].[' + @DatabaseName + '].sys.database_role_members drm 
     JOIN [LinkedServer].[' + @DatabaseName + '].sys.database_principals dp 
      ON drm.member_principal_id = dp.principal_id 
     JOIN [LinkedServer].[' + @DatabaseName + '].sys.database_principals dp2 
      ON drm.role_principal_id = dp2.principal_id 
     JOIN [LinkedServer].[master].[sys].[servers] s on 1=1 
WHERE 
     dp2.name in 
(''db_owner'',''db_accessadmin'',''db_securityadmin'',''db_ddladmin'') 
     AND s.server_id = 0 
     AND dp.name not in (''dbo'') 
     AND dp.type != ''R'' 
') 

FETCH NEXT FROM c1 
INTO @DatabaseName 
END 
CLOSE c1; 
DEALLOCATE c1; 
GO  

시도 : 여기

내 코드입니다

SELECT distinct (dp.name) as ''DatabaseUser'', 
     s.name as ''ServerName'', 
     ' + @DatabaseName + ' as ''Database'', 
     getdate() as ''date'' 

나는이 작업을 수행 할 때, 나는 다음과 같은 오류 얻을 : Msg 207, Level 16, State 1, Line 5 Invalid column name 'myTestDatabase'.

가 어떻게 설정 할 수 있습니다 이 상황에서 문자열을 변수로?

+0

변수에 데이터베이스 이름이 있습니다. 대신 DB_NAME 사용 '+ @DatabaseName +'데이터베이스 –

+0

구별 (dp.name)를 선택하면 'DatabaseUser' ','서버 이름 '' '로 \t \t s.name, \t \t '+ @DatabaseName + '로\t \t getdate() 'date' ' 구문이 잘못되었을 수 있지만이를 시도 할 때 다음 오류 메시지가 나타납니다. 메시지 207, 수준 16, 상태 1, 줄 5 'mytestDatabase'열 이름이 잘못되었습니다. – user3220707

+0

문자열로 만들어야합니다. 아마 문자열 리터럴의 양쪽에 ""있어야 할 것입니다. 질문에 코드를 게시 할 수 있습니까? 주석의 서식은 끔찍합니다. –

답변

2

작은 따옴표로 열 별칭을 래핑하는 습관이 없어야합니다. 그것들은 문자열 리터럴이 아니며 여러분의 코드를 읽기가 더 어렵게 만듭니다. 그것은 또한 동적 SQL과 함께 고뇌 많이 발생합니다.

다음은 사용자의 값을 캡처하여 여분의 작은 따옴표없이이 문자열을 작성하는 방법의 예입니다.

declare @SQL nvarchar(max) = 
'SELECT distinct (dp.name) as DatabaseUser, 
     s.name as ServerName, 
     ''' + @DatabaseName + ''' as Database, 
     getdate() as [date]' 
+0

대단히 고마워, 션! 큰 따옴표로 시도했지만, 이제 왜 왜 3 번 진드기를 사용해야하는지 알 수 있습니다. 나는 상대적으로 t-SQL에 익숙하지 않았으며, 나의 쿼리를 작업하기 위해 문서를 훑어보기가 어려웠다. 나는 기존의 코드를 구축하고 있지만, 앞으로는 이런 유형의 것을 피하려고 노력할 것이다. – user3220707