서버 주체가 SQL Server MS 2012의 현재 보안 컨텍스트에서 데이터베이스에 액세스할 수 없습니다.
Studio를 통해 서버의 합니다.만, SQL Server Management Studio 는 문제가 없습니다.로그인 할 때까지 문제 없습니다만, 명령어를 사용하면 됩니다.use myDatabase
하다
The server principal "****" is not able to access the database "****" under the current security context.
검색해 보니 호스팅 서비스 프로바이더가 이 문제를 해결했습니다.
SQL Server Management Studio 2008 용이지만 SQL Server Management Studio 2012를 사용하고 있기 때문에 이 방법은 사용할 수 없습니다.
이게 문제가 될 수 있나요?그리고 만약 그렇다면 SSMS 2012의 대안을 말해줄 수 있는 사람이 있나요?
사용자가 로그인하려는 DB에 매핑되어 있는지 확인합니다.
SQL 로그인은 데이터베이스 레벨이 아닌 서버 수준에서 정의되며 특정 데이터베이스의 사용자에게 매핑되어야 합니다.
SSMS 오브젝트익스플로러에서 변경할 서버에서 [Security]> [ Logins ]를 펼쳐 적절한 로그인 엔트리를 더블 클릭합니다.그러면 "로그인 속성" 대화상자가 나타납니다.
[사용자 매핑]을 선택하면 서버의 모든 데이터베이스가 표시됩니다.해당 로그인에 이미 매핑된 사용자가 있는 사용자에게는 "맵" 체크박스가 선택됩니다.여기서 추가 데이터베이스를 선택하고(각 데이터베이스에서 사용자가 속해야 하는 역할을 선택해야 함) [확인]을 클릭하여 매핑을 추가할 수 있습니다.
혼란을 피하기 위해 로그인과 동일한 사용자 이름을 지정하는 것이 일반적이지만 일치할 필요는 없으며 원하는 사용자 이름을 지정할 수 있습니다.
이러한 매핑은 복원 또는 유사한 작업 후에 연결이 끊길 수 있습니다.이 경우 사용자는 데이터베이스에 존재할 수 있지만 실제로는 로그인에 매핑되지 않습니다.이 경우 다음을 수행하여 로그인을 복원할 수 있습니다.
USE {database};
ALTER USER {user} WITH login = {login}
DB 사용자를 삭제하고 로그인 속성 대화 상자에서 다시 생성할 수도 있지만 역할 구성원 자격 또는 기타 설정을 다시 생성해야 합니다.
PROD 환경에서 SSRS에 보고서를 배포하는 데 동일한 오류가 발생했습니다.이 문제는 "use" 문구를 사용하여 재현될 수도 있는 것으로 나타났습니다.해결책은 사용자의 GUID 계정 참조를 해당 데이터베이스와 다시 동기화하는 것입니다(즉, db를 복원한 후처럼 "sp_change_users_login" 사용).모든 계정을 재동기화하는 스톡(커서 구동) 스크립트가 첨부되어 있습니다.
USE <your database>
GO
-------- Reset SQL user account guids ---------------------
DECLARE @UserName nvarchar(255)
DECLARE orphanuser_cur cursor for
SELECT UserName = su.name
FROM sysusers su
JOIN sys.server_principals sp ON sp.name = su.name
WHERE issqluser = 1 AND
(su.sid IS NOT NULL AND su.sid <> 0x0) AND
suser_sname(su.sid) is null
ORDER BY su.name
OPEN orphanuser_cur
FETCH NEXT FROM orphanuser_cur INTO @UserName
WHILE (@@fetch_status = 0)
BEGIN
--PRINT @UserName + ' user name being resynced'
exec sp_change_users_login 'Update_one', @UserName, @UserName
FETCH NEXT FROM orphanuser_cur INTO @UserName
END
CLOSE orphanuser_cur
DEALLOCATE orphanuser_cur
저는 이 문제에 대해 한참을 고민하다가 제가 어떤 데이터베이스로 접속해야 하는지 잊어버린 단순한 실수를 저질렀다는 것을 깨달았습니다.표준 SQL Server 연결 창을 사용하여 자격 증명을 입력했습니다.
연결할 데이터베이스를 올바르게 선택하고 있는지 확인하기 위해 연결 속성 탭을 확인해야 했습니다.실수로 [데이터베이스에 연결(Connect to database)]옵션을 이전 세션에서 선택한 상태로 두었습니다.이것이 내가 접속하려고 한다고 생각했던 데이터베이스에 접속할 수 없었던 이유입니다.
, 이 클릭을 합니다.Options >>
버튼을 클릭하여 [Connection Properties]
이 방법은 효과가 있었습니다.
use <Database>
EXEC sp_change_users_login @Action='update_one', @UserNamePattern='<userLogin>',@LoginName='<userLogin>';
이 문제는 다음 방법으로 시각화할 수 있습니다.
SELECT sid FROM sys.sysusers WHERE name = '<userLogin>'
SELECT sid FROM sys.syslogins WHERE name = '<userLogin>';
이 사건 전에 내 프린지 사건을 해결하기 위한 훌륭한 답변은 하나도 없었어.이 경우 저장 프로시저를 실행하기 위한 호출 전에 "사용자로서 실행" 스테이트먼트가 있었습니다만, 그 프로시저는 다른 DB의 테이블에서 읽혀졌습니다.사용자가 sysadmin이었지만 sproc는 "현재 보안 컨텍스트에서" 두 번째 데이터베이스에 액세스할 수 없기 때문에 실패했습니다.이것은 생산에서는 동작하고 있었지만, 개발 환경에서는 실패했습니다.프로덕션에서는 초기 데이터베이스에서는 신뢰성이 "on"으로 설정되었지만 개발 중에는 해당 데이터베이스에서는 해제된 것으로 확인되었습니다.데이터베이스를 복원하는 경우(가끔 개발 환경에 프로덕션 DB를 복원하는 경우) 신뢰할 수 있는 기능이 해제되는 효과가 있다고 읽었습니다.dev에서 "on"으로 설정하면 사용자는 두 번째 데이터베이스에 대한 읽기 액세스를 할 수 있습니다.
내 경우, 메시지는 실수로 "객체 이름"에 데이터베이스 이름을 포함시킨 동의어로 인해 발생했습니다.데이터베이스를 새 이름으로 복원해도 동의어가 여전히 이전 DB 이름을 가리킵니다.사용자에게 이전 DB에 대한 권한이 없기 때문에 메시지가 표시되었습니다.수정하기 위해 개체 이름을 데이터베이스 이름으로 한정하지 않고 동의어를 삭제하고 다시 만들었습니다.
USE [new_db]
GO
/****** Object: Synonym [dbo].[synTable] Script Date: 10/15/2015 9:45:01 AM ******/
DROP SYNONYM [dbo].[synTable]
GO
/****** Object: Synonym [dbo].[synTable] Script Date: 10/15/2015 9:45:01 AM ******/
CREATE SYNONYM [dbo].[synTable] FOR [dbo].[tTheRealTable]
GO
데이터베이스 사용자를 생성할 때 "Grant Connect To" 문이 누락되었을 수 있습니다.
다음은 SQL Server DBMS에 대한 로그인과 데이터베이스에 대한 사용자 로그인을 모두 작성하기 위해 필요한 완전한 스니펫입니다.
USE [master]
GO
CREATE LOGIN [SqlServerLogin] WITH PASSWORD=N'Passwordxyz', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
GO
USE [myDatabase]
GO
CREATE USER [DatabaseUser] FOR LOGIN [SqlServerLogin] WITH DEFAULT_SCHEMA=[mySchema]
GO
GRANT CONNECT TO [DatabaseUser]
GO
-- the role membership below will allow you to run a test "select" query against the tables in your database
ALTER ROLE [db_datareader] ADD MEMBER [DatabaseUser]
GO
사용자가 로그인에 올바르게 매핑되어 있는데도 동일한 오류가 발생했습니다.
사용자를 삭제하려고 한 결과 일부 SP에 해당 사용자가 "with execute as"로 포함되어 있는 것을 발견했습니다.
이 문제는 이러한 SP를 삭제하고 사용자를 삭제하며 로그인에 연결된 사용자를 재생성하고 SP를 재생성하여 해결되었습니다.
백업에서 복원(관련 로그인이 존재하지 않는 시간 동안) 또는 벌크 스키마 동기화(사용자가 존재하지 않는 경우에도 execute를 사용하여 SP를 생성할 수 있는 경우)로 인해 이 상태가 되었을 수 있습니다.이 답변과 관련이 있을 수도 있습니다.
vb.net에서 SMO(Server Management Objects)를 사용하는 동안 동일한 오류가 발생했습니다(C#에서도 마찬가지일 것입니다).
Techie Joe의 첫 번째 게시물에 대한 코멘트는 공유 호스팅에서 많은 추가 작업이 진행 중이라는 유용한 경고였습니다.알아내는 데 시간이 좀 걸렸지만, 아래 코드는 SQL 데이터베이스에 액세스하는 방법을 구체적으로 보여 줍니다.공유 호스팅 환경에서 SMO 호출이 정확하게 특정되지 않을 때마다 '서버 주체...' 오류가 나타나는 것 같습니다.
이 코드의 첫 번째 섹션은 로컬 SQL Express 서버에 대한 것으로 단순한 Windows 인증에 의존했습니다.이러한 샘플에 사용되는 모든 코드는 이 코드프로젝트 웹사이트 문서에 기재된 Robert Kanasz의 SMO 튜토리얼에 기초하고 있습니다.
Dim conn2 = New ServerConnection()
conn2.ServerInstance = "<local pc name>\SQLEXPRESS"
Try
Dim testConnection As New Server(conn2)
Debug.WriteLine("Server: " + testConnection.Name)
Debug.WriteLine("Edition: " + testConnection.Information.Edition)
Debug.WriteLine(" ")
For Each db2 As Database In testConnection.Databases
Debug.Write(db2.Name & " - ")
For Each fg As FileGroup In db2.FileGroups
Debug.Write(fg.Name & " - ")
For Each df As DataFile In fg.Files
Debug.WriteLine(df.Name + " - " + df.FileName)
Next
Next
Next
conn2.Disconnect()
Catch err As Exception
Debug.WriteLine(err.Message)
End Try
위의 코드는 로컬 SQLEXPRESS 서버상의 모든 데이터베이스의 .mdf 파일은 정상적으로 검출됩니다.이는 인증이 Windows에 의해 처리되고 모든 데이터베이스에 걸쳐 적용되기 때문입니다.
다음 코드에는 .mdf 파일에 대해 2개의 섹션이 반복되어 있습니다.이 경우 파일 그룹을 찾는 첫 번째 반복만 작동하고 공유 호스팅 환경의 단일 데이터베이스에만 연결되므로 단일 파일만 찾습니다.
위에서 동작한 반복의 복사본인 두 번째 반복은 사용자 ID/비밀번호가 적용되지 않는 공유 환경의 첫 번째 데이터베이스에 액세스하려고 하기 때문에 SQL 서버가 'server principal...' 오류 형식으로 인증 오류를 반환합니다.
Dim sqlConnection1 As New System.Data.SqlClient.SqlConnection
sqlConnection1.ConnectionString = "connection string with User ID/Password to a specific database in a shared hosting system. This string will likely also include the Data Source and Initial Catalog parameters"
Dim conn1 As New ServerConnection(sqlConnection1)
Try
Dim testConnection As New Server(conn1)
Debug.WriteLine("Server: " + testConnection.Name)
Debug.WriteLine("Edition: " + testConnection.Information.Edition)
Debug.WriteLine(" ")
Dim db2 = testConnection.Databases("the name of the database to which the User ID/Password in the connection string applies")
For Each fg As FileGroup In db2.FileGroups
Debug.Write(fg.Name & " - ")
For Each df As DataFile In fg.Files
Debug.WriteLine(df.Name + " - " + df.FileName)
Next
Next
For Each db3 As Database In testConnection.Databases
Debug.Write(db3.Name & " - ")
For Each fg As FileGroup In db3.FileGroups
Debug.Write(fg.Name & " - ")
For Each df As DataFile In fg.Files
Debug.WriteLine(df.Name + " - " + df.FileName)
Next
Next
Next
conn1.Disconnect()
Catch err As Exception
Debug.WriteLine(err.Message)
End Try
두 번째 반복 루프에서는 코드는 정상적으로 컴파일되지만 SMO는 정확한 구문을 사용하여 정확한 데이터베이스에 액세스하도록 설정되어 있지 않기 때문에 이 시도는 실패합니다.
SMO를 배운 지 얼마 되지 않았기 때문에 다른 신입사원들도 이 오류에 대한 더 간단한 설명이 있다는 것을 알고 기뻐할 것이라고 생각했습니다. 단지 코드를 잘못 입력했을 뿐입니다.
SQL 2017 - 데이터베이스 A와 데이터베이스 B의 유사어가 있습니다.사용자는 데이터베이스 A에 연결할 수 있으며 B를 가리키는 동의어를 참조하는 sp(A의 경우)에 대한 exec 권한을 가집니다.사용자가 접속 액세스 B로 설정되었습니다.데이터베이스 B에 공용 그룹에 CONNECT를 부여할 때만 A의 SP가 작동했습니다.2012년에는 사용자에게만 접속을 허용하는 것이 효과가 있는 것처럼 보였기 때문에 이 방법으로 작동한 것은 기억나지 않습니다.
이 문제는 로그인하지 않은 사용자가 데이터베이스를 다른 서버로 백업 및 복원한 후 사용자가 데이터베이스와의 연결을 끊은 경우에 한정됩니다.
문제를 해결하려면 사용자가 데이터베이스에 연결되어 있는지 확인해야 했습니다.
GRANT CONNECT TO [DatabaseUser]
GO
이는 위의 Salim Gangji의 답변과 유사하지만 로그인하지 않은 사용자만의 답변입니다.
사용방법:
DECLARE @sql VARCHAR(255)
DECLARE @owner VARCHAR(255)
WHILE EXISTS (SELECT DISTINCT S.name AS owner
FROM sys.schemas s, sys.database_principals u
WHERE s.principal_id = u.principal_id
AND u.name NOT IN( 'dbo' ,'guest','sys','INFORMATION_SCHEMA')
AND u.name NOT LIKE 'db_%')
BEGIN
SET @owner = (SELECT DISTINCT TOP(1) s.name
FROM sys.schemas s, sys.database_principals u
WHERE s.principal_id = u.principal_id
AND u.name NOT IN( 'dbo' ,'guest','sys','INFORMATION_SCHEMA')
AND u.name NOT LIKE 'db_%')
SET @sql = 'ALTER AUTHORIZATION ON SCHEMA::' + @owner + ' TO dbo'
PRINT @sql
exec (@sql)
END
DECLARE @name varchar(500)
DECLARE @db varchar(100)= DB_NAME()
DECLARE @strQuery varchar(1000)='use '+ @db
DECLARE consec CURSOR FOR
select name from sys.sysusers WHERE hasdbaccess=1 and name not in ('dbo','guest') /*and name not like 'esfcoah%'*/ AND status=0
OPEN consec
FETCH NEXT FROM consec INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
set @strQuery='use ['+@db+']'
exec(@strQuery)
if exists(select * from sys.schemas where name like @name)
begin
set @strQuery='DROP SCHEMA ['
set @strQuery=@strQuery+@name+']'
exec(@strQuery)
end
set @strQuery='DROP USER ['
set @strQuery=@strQuery+@name+']'
exec(@strQuery)
set @strQuery='USE [master]'
exec (@strQuery)
if not exists(select * from sys.syslogins where name like @name)
begin
set @strQuery='CREATE LOGIN ['+@name+'] WITH PASSWORD=N''a'', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF'
exec (@strQuery)
end
set @strQuery='use ['+@db+']'
exec(@strQuery)
set @strQuery='CREATE USER ['+@name+'] FOR LOGIN ['+@name+']'
exec(@strQuery)
set @strQuery='EXEC sp_addrolemember N''db_owner'', N'''+@name+''''
exec(@strQuery)
FETCH NEXT FROM consec INTO @name
end
close consec
deallocate consec
이는 서버가 액세스하려는 원하는 데이터베이스와 매핑되지 않았기 때문입니다.
다음과 같은 작업을 수행할 수 있습니다.
- 서버의 보안 폴더로 이동합니다.
- 두 번 클릭하고 로그인 폴더로 이동합니다.
- 사용자 ID를 찾아 두 번 클릭합니다.
- 로그인 속성 창이 열립니다.
- 여기서 User Mapping으로 이동합니다.
- 해당 로그인에 매핑할 모든 데이터베이스를 선택합니다.
이러한 현상이 발생하는 이유는 사람마다 다르기 때문에 다음과 같습니다.
저장 프로시저가 호출한 데이터베이스에 대해 이 메시지를 받았습니다.두에서 올바르게 되어 있으며 JobAgentManager를 할 수 .@database_user_name=N'JobAgentManager',
스크립트에 있음)를 참조해 주세요.command='exec mystoredproc'
를 참조해 주세요.
언급URL : https://stackoverflow.com/questions/19009488/the-server-principal-is-not-able-to-access-the-database-under-the-current-securi
'programing' 카테고리의 다른 글
일별로 그룹화할 SQL 쿼리 (0) | 2023.04.07 |
---|---|
SQL Server:크로스 조인(CROSS JOIN)과 풀 아우터 조인(FULL OUTER JOIN)의 차이점은 무엇입니까? (0) | 2023.04.07 |
Angular에서 $location으로 리디렉션하는 방법.path를 $120으로 지정합니다.성공 후 콜백 (0) | 2023.04.02 |
angular.js 뷰에서 사용하기 전에 스코프 변수가 로드될 때까지 기다립니다. (0) | 2023.04.02 |
타이프스크립트에서 enum을 인덱스 키 유형으로 사용하는 방법 (0) | 2023.04.02 |