Esencialmente combinando David's answer y marc_s's answer, según lo solicitado por un comentario de Chris.
Libros en pantalla de sp_grantdbaccess dice:
Esta característica se quitará en una versión futura de Microsoft SQL servidor. Evite utilizar esta función en el nuevo trabajo de desarrollo , y planifique modifique las aplicaciones que actualmente usan esta función. Use CREATE USER en su lugar.
Así que sólo crear un usuario si éste no existe, yo haría algo como esto:
/* Make sure User is created in the appropriate database. */
USE mydb
GO
/* Users are typically mapped to logins, as OP's question implies,
so make sure an appropriate login exists. */
IF NOT EXISTS(SELECT principal_id FROM sys.server_principals WHERE name = 'foo') BEGIN
/* Syntax for SQL server login. See BOL for domain logins, etc. */
CREATE LOGIN foo
WITH PASSWORD = 'sufficiently complex password'
END
/* Create the user for the specified login. */
IF NOT EXISTS(SELECT principal_id FROM sys.database_principals WHERE name = 'foo') BEGIN
CREATE USER foo FOR LOGIN foo
END
A pesar de estar en desuso, sp_grantdbaccess tiene la ventaja de ser capaz de utilizar un parámetro o variable local para el nombre de usuario/inicio de sesión, como en la respuesta de David. La primera alternativa que pude pensar para obtener algo similar para trabajar con CREATE USER fue usar SQL dinámico. Por ejemplo:
/* Make sure User is created in the appropriate database. */
USE mydb
GO
DECLARE @NewUserName sysname;
DECLARE @NewUsersLogin sysname;
SET @NewUserName = 'foo';
SET @NewUsersLogin = 'bar';
/* Users are typically mapped to logins, as OP's question implies,
so make sure an appropriate login exists. */
IF NOT EXISTS(SELECT principal_id FROM sys.server_principals WHERE name = @NewUsersLogin) BEGIN
/* Syntax for SQL server login. See BOL for domain logins, etc. */
DECLARE @LoginSQL as varchar(500);
SET @LoginSQL = 'CREATE LOGIN '+ @NewUsersLogin +
' WITH PASSWORD = ''sufficiently complex password''';
EXEC (@LoginSQL);
END
/* Create the user for the specified login. */
IF NOT EXISTS(SELECT principal_id FROM sys.database_principals WHERE name = @NewUserName) BEGIN
DECLARE @UserSQL as varchar(500);
SET @UserSQL = 'CREATE USER ' + @NewUserName + ' FOR LOGIN ' + @NewUsersLogin;
EXEC (@UserSQL);
END
Curiosamente, los libros en pantalla también dice que en realidad llama sp_grantdbaccess
CREATE USER
, y me di cuenta en mi prueba de que si no se asigna explícitamente un esquema, sp_grantdbaccess
va a crear un nombre de usuario, mientras CREATE USER
usará 'dbo' por defecto.
posible duplicado de [Comprobación de si un inicio de sesión de SQL Server ya existe] (http: // stackoverflow.com/questions/1379437/checking-if-a-sql-server-login-already-exists) – bummi