クライアントの1つからデータベースバックアップを1つ受け取りましたが、それをシステムに復元しようとしています。
私はグーグルでこの問題を検索しようとし、提案されたソリューションのほとんどを試しましたが、どれも機能していません。データベースの復元後、このエラーの具体的な解決策を誰かが提案できますか?
前もって感謝します!
データベースを復元すると、database usersが含まれます。これらのユーザーは、別のSQL Serverへのバックアップと復元を実行するたびに、データベースとともに転送されます。
ソースSQLサーバーとターゲットSQLサーバーには、SQLサーバーログインがあります。これらのログインは、SQL Serverアカウント(ネイティブSQL Serverログイン)またはWindowsサーバー/ドメインアカウント(Windowsアカウント)のいずれかです。
SQL Serverログイン(ネイティブSQLログインまたはWindowsアカウント)はmasterデータベースに格納され、各SQLログインに一意のSIDが割り当てられています。システムカタログビュー sys.server_principals
をクエリすると、SQL Serverログインのリストを取得できます。
select * from sys.server_principals
SQL ServerインスタンスのSQL Serverログインのリストを受け取ります。
注:これらはSQL Serverログインであり、データベースユーザーではありません。
次のクエリを発行して、各ユーザーデータベースのシステムカタログビュー sys.database_principles
をクエリすることで、データベースユーザーにクエリを実行できます。
USE [<your_db>]
GO
SELECT * FROM sys.database_principals
データベース特権が割り当てられているデータベースユーザーのリストが表示されます。
注:これらはデータベースユーザーであり、SQL Serverログインではありません。
データベースを作成し、特定の権限を持つ「ユーザー」をデータベースに割り当てると、実際には次のことを行います(一部はバックグラウンドで)。
sys.server_principal
)を使用したSQL Serverログインの作成sys.database_principal
)この場合、SQLログインのSID(sys.server_principal
)は、データベースユーザーのSID(sys.database_principal
)と一致します。
ソースSQL Serverからデータベースを復元すると、ソースデータベースのデータベースユーザー(ネイティブSQL ServerログインとローカルWindowsアカウントのみ)のSIDが異なりますターゲットサーバー上のSQL Server Loginsよりも。これは、SIDがソースとターゲットのネイティブSQL ServerログインまたはローカルWindowsアカウントで一意であるためです。
SQL Serverはこれらの値をActive Directoryから取得するため、Windowsドメインアカウントに基づくSQL Serverログインは常に同じSIDを持ちます。
データベースをソースからターゲットのSQL Serverに復元すると、ユーザーがSQL Serverインスタンスのsys.server_principals
システム管理カタログにリストされていても、ネイティブSQL ServerログインのSIDが一致しませんsys.database_principals
復元されたデータベースのシステム管理カタログ。
これを修正し、「SQL Serverログイン|権限」または「データベースプロパティ|権限」をナビゲートできるようにするには、これらの孤立したデータベースユーザーをSQL Serverログインに再リンクします。
ユーザーデータベースに切り替えて、孤立したデータベースユーザーをクエリします。
USE [your_db]
GO
sp_change_users_login 'Report'
ユーザーが孤立していると報告された場合は、SQL Serverログインをデータベースユーザー次のコマンドを発行します。
USE [your_db]
GO
sp_change_users_lgoin 'Update_one', '<database_user>', '<sql_server_login>'
これにより、ターゲットインスタンスの(ネイティブ)SQL Serverログイン(sys.server_principal
)が、復元されたデータベースのデータベースユーザー(sys.database_principal
)に再リンクされます。
sp_change_users_login
は非推奨であるため、- ALTER USER
ステートメントで同じことを実現できます。
USE [<your_db>]
GO
ALTER USER <database_user>
WITH LOGIN = <sql_server_login>
...クライアントからデータベースバックアップを受け取ったときに、データベースユーザーにリンクするための対応するSQL Serverログインがない場合があります。その場合は、復元したデータベースに権限を割り当てずにSQL Serverログインを作成し、新しく作成したSQL Serverログインを上記のステートメントを使用してデータベースユーザーにリンクできます。
表示されているエラーは、SSMSダイアログ(画像上)が起動するコードに由来します。
そのダイアログを介して一部のユーザーの有効な権限についてサーバーに尋ねると、サーバーは選択されたユーザーを偽装しようとします。つまり、test_user
、effective permissions
起動するコードは次のとおりです。
EXECUTE AS USER = N'test_user';
SELECT
permission_name AS [Permission]
FROM fn_my_permissions(N'[yourDB]', N'DATABASE')
ORDER BY permission_name;
REVERT;
これは、ユーザー(test_user)がログインなしで作成された場合です。
ユーザーが対応するログインを持っている場合、サーバーはその対応するログインを偽装しようとします。これは、login = win groupの場合、より多くのユーザーに対応する可能性があるためです。
たとえば、ユーザーがcertificate
から作成される場合もありますが、この場合に実行されるコードを監視できません。
SQL Server Profilerを使用するだけで、サーバーでどのコードが実行されるかを確認するには、偽装しようとしているものを特定して、エラーの原因を見つけます。
私はWindowsグループの特定のケースでこのエラーを受け取る方法を知っています:偽装することはできないため、正確にそのエラーが発生します。
その他の考えられる原因:そのユーザーを偽装する権限がない可能性があります。コードをsysadmin
として実行していますか?そうでない場合、これはあなたのケースである可能性があります
[〜#〜]更新[〜#〜]
たった今再現できました。 復元されたデータベースを別のサーバーに移植した孤立したユーザーは、偽装しようとすると同じエラーが発生します。
孤立したユーザーと同じ名前の(sidが異なる)ログインが存在する場合は、次のコードを実行してこれを修正できます。
alter user test_user with login = test_user
対応するログインがない場合は、同じsidで再作成するか、新しいログインを作成して、上記のように既存のユーザーを更新します。
このユーザーがまったく必要ない場合は、ドロップしてください