Как проверить, существует ли логин на уровне SQL Server … различное поведение между базами данных

#sql #sql-server #sql-server-2008

#sql #sql-server #sql-сервер-2008

Вопрос:

У меня происходит что-то очень странное. Мне нужно создать пользователя из моего приложения и создать для этого хранимую процедуру.

 ALTER PROCEDURE [dbo].[P_CREATEUSER]
  -- Add the parameters for the stored procedure here
  @LoginName NVARCHAR(50)
, @Password  NVARCHAR(50)
  WITH EXECUTE AS 'WMSApplicatieAdmin'
AS
BEGIN
  -- SET NOCOUNT ON added to prevent extra result sets from
  -- interfering with SELECT statements.
  SET NOCOUNT ON;

  PRINT 'P_CREATEUSER'

  -- Insert statements for procedure here
  DECLARE @DBNAME NVARCHAR(128);

  SELECT @DBNAME = DB_NAME( );

  DECLARE @SQL NVARCHAR(MAX) = '';

  IF (@Password IS NULL)
  BEGIN
    SET @Password = '';
  END


  IF NOT EXISTS (SELECT name
        FROM master.sys.server_principals
        WHERE name = @LoginName)
  BEGIN
    PRINT '@loginname = '   COALESCE( @LoginName, 'NULL' )
    SET @SQL = 'CREATE LOGIN ['   @LoginName   '] WITH PASSWORD = '''   @Password   ''', DEFAULT_DATABASE=['   @DBNAME   '], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF';
    PRINT @SQL
    EXECUTE (@SQL);
    PRINT 'Created Login'
  END

  IF NOT EXISTS (SELECT name
        FROM sys.database_principals
        WHERE name = @LoginName)
  BEGIN
    SET @SQL = 'CREATE USER ['   @LoginName   '] FOR LOGIN ['   @LoginName   ']';
    PRINT @SQL
    EXECUTE (@SQL);
    PRINT 'Created User'
  END
END
 

Так вот, обычно это должно работать нормально. Я протестировал его в нашей базе данных разработчиков, и он работает нормально. Однако в производственной базе данных этого не происходит. Странно то, что SELECT from server_principals возвращает разные результаты в базе данных разработчиков, чем в базе данных PRD.

В моей базе данных PRD он возвращает только следующие записи :

 SELECT name
  FROM master.sys.server_principals

name
sa
public
sysadmin
securityadmin
serveradmin
setupadmin
processadmin
diskadmin
dbcreator
bulkadmin
 

Хотя в базе данных разработчиков он корректно возвращает приведенный выше набор, но также и все созданные логины. Я понятия не имею, что может быть причиной этой проблемы или что я делаю не так, поэтому я надеюсь, что кто-нибудь здесь сможет мне помочь.

Обновить

У меня есть подозрение, что это как-то связано с ролью приложения. Даже в SQL Server я получаю только 10 перечисленных элементов при использовании следующего оператора :

 DECLARE @MyCoockie VARBINARY(MAX)

EXECUTE sys.sp_setapprole @rolename = 'WMSApplicatie' /* SYSNAME */
                        , @password = @MyPassword /* SYSNAME */
                        , @encrypt = 'None' /* VARCHAR(10) */
                        , @fCreateCookie = 1 /* BIT */
                        , @cookie = @MyCoockie OUT

SELECT NAME
  FROM sys.server_principals

EXECUTE sys.sp_unsetapprole @cookie = @MyCoockie
 

Заранее большое спасибо.

Комментарии:

1. Попробуйте войти в систему с помощью sa или admin.

Ответ №1:

Похоже, что ваш производственный сервер имеет дополнительную защиту, которая не позволяет вашему логину видеть имена пользователей. Это было бы нормально для производственного сервера. Вероятно, существует процесс добавления этих логинов в рабочую среду.

Комментарии:

1. Привет … обе базы данных находятся на одном SQL-сервере. Когда я смотрю на SQL Server, я могу четко видеть всех пользователей.

2. Я замечаю, что это может иметь какое-то отношение к роли приложения, которая устанавливается при запуске приложения :