Після переміщення бази даних з екземпляра SQL Server на сервері A в екземпляр SQL Server на сервері B, можливо, користувачі не зможуть увійти в базу даних на сервері B. Крім того, може виникати таке повідомлення про помилку: Помилка входу користувача "користувач". (Microsoft SQL Server, помилка: 18456). Ця проблема виникає через те, що імена входу і паролі були переміщені з примірника SQL Server на сервері A в екземпляр SQL Server на сервері B.
Для вирішення даного завдання необхідно слідувати наступним алгоритмом:
1. На сервері A за допомогою програми «Адміністратор баз даних» (Адміністратор MSDE) підключитися до примірника SQL Server, з якого переміщена база даних (при наявності встановленого Microsoft SQL Server можна скористатися SQL Server Management Studio (або SQL Manager).
Увага. для коректного виконання сценарію необхідно спочатку скопіювати текст сценарію з даного керівництва в програму WordPad. потім з програми WordPad скопіювати текст в програму Блокнот.
IF OBJECT_ID ( 'sp_hexadecimal') IS NOT NULL
DROP PROCEDURE sp_hexadecimal
CREATE PROCEDURE sp_hexadecimal
@hexvalue varchar (514) OUTPUT
DECLARE @charvalue varchar (514)
DECLARE @length int
DECLARE @hexstring char (16)
SELECT @charvalue = '0x'
SELECT @length = DATALENGTH (@binvalue)
SELECT @hexstring = '0123456789ABCDEF'
WHILE (@i <= @length)
DECLARE @tempint int
DECLARE @firstint int
DECLARE @secondint int
SELECT @tempint = CONVERT (int, SUBSTRING (@ binvalue, @ i, 1))
SELECT @firstint = FLOOR (@ tempint / 16)
SELECT @secondint = @tempint - (@ firstint * 16)
SELECT @charvalue = @charvalue +
SUBSTRING (@hexstring, @ firstint + 1, 1) +
SUBSTRING (@hexstring, @ secondint + 1, 1)
SELECT @hexvalue = @charvalue
IF OBJECT_ID ( 'sp_help_revlogin') IS NOT NULL
DROP PROCEDURE sp_help_revlogin
CREATE PROCEDURE sp_help_revlogin @login_name sysname = NULL AS
DECLARE @name sysname
DECLARE @type varchar (1)
DECLARE @hasaccess int
DECLARE @denylogin int
DECLARE @is_disabled int
DECLARE @PWD_varbinary varbinary (256)
DECLARE @PWD_string varchar (514)
DECLARE @SID_varbinary varbinary (85)
DECLARE @SID_string varchar (514)
DECLARE @tmpstr varchar (1024)
DECLARE @is_policy_checked varchar (3)
DECLARE @is_expiration_checked varchar (3)
DECLARE @defaultdb sysname
IF (@login_name IS NULL)
DECLARE login_curs CURSOR FOR
SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
sys.server_principals p LEFT JOIN sys.syslogins l
ON (l.name = p.name) WHERE p.type IN ( 'S', 'G', 'U') AND p.name <> 'Sa'
DECLARE login_curs CURSOR FOR
SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM
sys.server_principals p LEFT JOIN sys.syslogins l
ON (l.name = p.name) WHERE p.type IN ( 'S', 'G', 'U') AND p.name = @login_name
FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
IF (@@ fetch_status = -1)
PRINT 'Eiaia ia iaeaaiu.'
SET @tmpstr = '/ * sp_help_revlogin script'
SET @tmpstr = '** Generated' + CONVERT (varchar, GETDATE ()) + 'on' + @@ SERVERNAME + '* /'
WHILE (@@ fetch_status <> -1)
IF (@@ fetch_status <> -2)
SET @tmpstr = '- Login:' + @name
IF (@type IN ( 'G', 'U'))
BEGIN - NT authenticated account / group
SET @tmpstr = 'CREATE LOGIN' + QUOTENAME (@name) + 'FROM WINDOWS WITH DEFAULT_DATABASE = [' + @defaultdb + ']'
ELSE BEGIN - SQL Server authentication
-- obtain password and sid
SET @PWD_varbinary = CAST (LOGINPROPERTY (@name, 'PasswordHash') AS varbinary (256))
EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT
EXEC sp_hexadecimal @ SID_varbinary, @ SID_string OUT
-- obtain password policy state
SELECT @is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name
SELECT @is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN 0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name
SET @tmpstr = 'CREATE LOGIN' + QUOTENAME (@name) + 'WITH PASSWORD =' + @PWD_string + 'HASHED, SID =' + @SID_string + ', DEFAULT_DATABASE = [' + @defaultdb + ']'
IF (@is_policy_checked IS NOT NULL)
SET @tmpstr = @tmpstr + ', CHECK_POLICY =' + @is_policy_checked
IF (@is_expiration_checked IS NOT NULL)
SET @tmpstr = @tmpstr + ', CHECK_EXPIRATION =' + @is_expiration_checked
IF (@denylogin = 1)
BEGIN - login is denied access
SET @tmpstr = @tmpstr + '; DENY CONNECT SQL TO '+ QUOTENAME (@name)
ELSE IF (@hasaccess = 0)
BEGIN - login exists but does not have access
SET @tmpstr = @tmpstr + '; REVOKE CONNECT SQL TO '+ QUOTENAME (@name)
IF (@is_disabled = 1)
BEGIN - login is disabled
SET @tmpstr = @tmpstr + '; ALTER LOGIN '+ QUOTENAME (@name) +' DISABLE '
FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin
Примітка. сценарій створює в базі даних master дві збережених процедури - sp_hexadecimal і sp_help_revlogin.
3. Виконайте наступний сценарій:
Сценарій, який створюється збереженої процедурою sp_help_revlogin. є сценарієм входу. Цей сценарій створює імена входу з вихідним ідентифікатором (ВД) безпеки і паролем.
4. На сервері B запустіть програму Адміністратор баз даних (Адміністратор MSDE) (при наявності встановленого Microsoft SQL Server можна скористатися SQL Server Management Studio (або SQL Manager)) і виконайте підключення до примірника SQL Server, на який переміщена база даних.
Увага. перед виконанням дії 5 прочитайте блок приміток нижче.
Перед виконанням вихідного сценарію в екземплярі на сервері B необхідно прочитати відомості, представлені нижче.
2. У вихідному сценарії імена входу створюються з зашифрованим паролем. Це пояснюється наявністю аргументу HASHED для оператора CREATE LOGIN. Цей аргумент вказує, що пароль, який вводиться після аргументу PASSWORD, вже хешірованного.
3. За замовчуванням тільки члени з визначеною роллю сервера sysadmin можуть виконувати оператор SELECT з уявлення sys.server_principals. Користувачі можуть створювати або виконувати кінцевий сценарій тільки в тому випадку, якщо член з визначеною роллю сервера sysadmin надасть їм необхідні дозволи.
4. При виконанні дій, описаних в даній статті, відомості бази даних за замовчуванням для певного імені входу не переміщаються. Це відбувається тому, що база даних за замовчуванням може бути відсутнім на сервері B. Щоб визначити базу даних за замовчуванням для входу, використовуйте оператор ALTER LOGIN, вказавши ім'я входу і базу даних за замовчуванням в якості аргументів.
5. При сортуванні на сервері A може не враховуватися регістр, а на сервері B - враховуватися. У цьому випадку після переміщення імен входу і паролів в екземпляр на сервері B користувачі повинні вводити паролі повністю прописними літерами.
6. Крім того, можливо, при сортуванні на сервері A враховується регістр, а на сервері B - не враховується. У цьому випадку користувачі не зможуть входити в систему з іменами і паролями, переміщеними в екземпляр на сервері B, якщо не виконується одна з наступних умов:
# 9642; вихідні паролі не містять букв;
# 9642; всі букви в початкових паролі прописні.
Якщо регістр враховується або не враховується при сортуванні одночасно на обох серверах, ця проблема не виникає.
7. Якщо ім'я входу, яке вже присутній в екземплярі на сервері B, збігається з ім'ям в вихідному сценарії, при виконанні сценарію в екземплярі на сервері з'явиться таке повідомлення про помилку:
Пові. 15025, Рівень 16, Стан 1, Рядок 1
Сервер-учасник "користувач" вже існує.
Якщо ім'я входу, яке вже присутній в екземплярі на сервері B, збігається з ІД безпеки в вихідному сценарії, при виконанні сценарію в екземплярі на сервері з'явиться таке повідомлення про помилку:
Пові. 15433, Рівень 16, Стан 1, Рядок 1
Зазначений ідентифікатор безпеки параметра використовується.
Отже, необхідно виконати такі дії.
# 9642; Виправте помилки, відповідні повідомленнями.