我试图通过SQL Server Management Studio访问我的托管服务器的数据库,所有内容直到登录都没问题,但是当我使用命令use myDatabase
时,它给了我这个错误:
The server principal "****" is not able to access the database "****" under the current security context.
我搜索了一下,托管服务提供商列出了this修复此问题的方法。
但这对我不起作用可能是因为它适用于SQL Server Management Studio 2008但是我使用的是SQL Server Management Studio 2012.
这可能是个问题吗?如果是,那么任何人都可以告诉我它在SSMS 2012中的替代方案吗?
答案 0 :(得分:73)
检查您的用户是否已映射到您尝试登录的数据库。
答案 1 :(得分:20)
我们在PROD环境中将报告部署到SSRS时遇到了同样的错误。人们发现这个问题甚至可以通过“使用”声明再现。解决方案是将用户的GUID帐户引用与相关数据库重新同步(即,像恢复数据库一样使用“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
答案 2 :(得分:7)
我花了很长时间来解决这个问题,然后我意识到我犯了一个简单的错误,因为我忘记了哪个特定的数据库是我的目标。我使用标准SQL Server连接窗口输入凭据:
我必须检查连接属性标签,以验证我是否选择了要连接的正确数据库。我不小心将连接到数据库选项保留在此处,设置为上一个会话中的选择。这就是为什么我无法连接到我想要连接的想到的数据库。
请注意,您需要点击Options >>
按钮才能显示连接属性和其他标签。
答案 3 :(得分:3)
就我而言,该消息是由同义词引起的,该同义词无意中将数据库名称包含在&#34;对象名称&#34;中。当我以新名称还原数据库时,同义词仍然指向旧的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
答案 4 :(得分:1)
这对我有用:
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>';
答案 5 :(得分:0)
我在vb.net中使用服务器管理对象(SMO)时遇到了同样的错误(我确信它在C#中是相同的)
Techie Joe对初始帖子的评论是一个有用的警告,即在共享主机中还有很多其他内容正在进行中。花了一点时间才弄明白,但下面的代码显示了如何在访问SQL数据库时非常具体。每当SMO调用在共享托管环境中没有精确具体时,“服务器主体......”错误似乎就会出现。
第一部分代码针对本地SQL Express服务器,依赖于简单的Windows身份验证。这些示例中使用的所有代码都基于Robert Kanasz在此Code Project website article中的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文件。在这种情况下,只有第一次迭代查找文件组才有效,并且它只找到一个文件,因为连接只是共享托管环境中的一个数据库。
第二次迭代,它是上面工作的迭代的副本,立即窒息,因为它写入的方式它试图访问共享环境中的第一个数据库,这不是用户ID /密码的那个apply,因此SQL Server以“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,我认为其他新手可能会欣赏知道这个错误还有一个更简单的解释 - 我们只是编错了。
答案 6 :(得分:0)
即使用户已正确映射到登录名,我们也会遇到相同的错误。
尝试删除用户后,发现有几个SP包含&#34;执行为&#34;那个用户。
通过删除这些SP,删除用户,重新创建链接到登录的用户以及重新创建SP来解决问题。
可能它处于这种状态,从备份恢复(在相关登录不存在的时间)或批量模式同步(如果可能创建具有执行的SP,即使用户没有&#39) ; t存在。也可能与this answer有关。
答案 7 :(得分:0)
SQL 登录是在服务器级别定义的,必须映射到特定数据库中的用户。
在SSMS对象浏览器中,要修改的服务器下,展开安全性> 登录,然后双击相应的用户,将弹出“登录属性”。 “对话框。
选择用户映射,它将显示服务器上的所有数据库,并选择已选择现有映射的数据库。在这里,您可以选择其他数据库(并确保选择用户应属于每个数据库中的哪个角色),然后单击确定添加映射。
在还原或类似操作之后,这些映射可能会断开连接。在这种情况下,用户可能仍然存在于数据库中,但实际上并未映射到登录名。如果发生这种情况,您可以运行以下命令来恢复登录名:
USE {database};
ALTER USER {user} WITH login = {login}
您还可以删除数据库用户,然后从“登录属性”对话框中重新创建它,但是任何角色成员身份或其他设置都需要重新创建。
答案 8 :(得分:0)
我相信您在创建数据库用户时可能会丢失“授权连接到”语句。
下面是完整的代码段,您将需要创建针对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
答案 9 :(得分:0)
在SQL 2017上-数据库A具有与数据库B的同义词。用户可以连接到数据库A,并且对sp(在A上)具有指向指向B的同义词的执行权限。仅当将对公共组的CONNECT授予数据库B时,A上的工作才会执行。我不记得在2012年以这种方式工作,因为授予与用户的连接似乎只是行得通。