【发布时间】:2023-03-24 19:00:01
【问题描述】:
我正在创建一个将用户登录名添加到特定数据库的过程。当用户插入我的数据库时,我在触发器中调用此过程(我希望我的站点中的每个用户和对数据库的访问都具有不同的登录名)。
这是我的触发器:
ALTER TRIGGER [dbo].[sys_users_insert]
ON [dbo].[sys_users]
AFTER INSERT
AS
BEGIN
DECLARE @USERNAME varchar(MAX)
SELECT @USERNAME = INSERTED.username
FROM INSERTED
EXEC CreateUser @USERNAME
END
CreateUser 是我在数据库中创建登录的过程。该程序正在运行。当我从查询编辑器调用它时:
EXEC CreateUser 'patricia.santos'
用户创建成功。但是当我在表中插入一个用户并触发运行时,用户既没有创建也没有插入到表中。我发现如果我在用户名中插入一个不带点的用户,一切都会好起来的。所以我相信是带点的东西,但我想知道是否有一些解决方法可以接受带点的用户名。
更新
这是我在数据库中创建登录的过程:
USE mydatabase
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[CreateUser]
@USERNAME AS VARCHAR(MAX) = ''
AS
BEGIN
declare @sql nvarchar(MAX)
If NOT EXISTS(select loginname from master.dbo.syslogins where name = @USERNAME)
BEGIN
set @sql = 'CREATE LOGIN ' + @USERNAME +
' WITH
PASSWORD = ''something'',
CHECK_POLICY = OFF'
exec(@sql)
set @sql = 'ALTER SERVER ROLE sysadmin ADD MEMBER ' + @username
exec(@sql)
IF NOT EXISTS (SELECT * FROM sys.database_principals WHERE name = @USERNAME)
BEGIN
-- Creates a database user for the login created above.
set @sql = 'CREATE USER [' + @USERNAME + '] FOR LOGIN [' + @USERNAME + ']'
exec(@sql)
EXEC sp_addrolemember 'db_owner', @USERNAME
END
END
END
谢谢你:)
【问题讨论】:
-
我不确定您的示例在任何情况下是如何工作的。在声明 @USERNAME 变量后没有其他变量声明后,您有一个逗号。这只是您的示例中的复制粘贴错误吗?
-
@EdmondQuinton 很抱歉,这是复制粘贴错误。已经编辑了我的问题。 :)
-
您的触发器有 MAJOR 缺陷,因为您似乎认为它会每行调用一次 - 那是不是 b> 情况。触发器将每条语句触发一次,因此如果您的
INSERT语句影响 25 行,您将触发触发器一次,但随后Inserted将包含 25行。您的代码将在这 25 行中选择哪一行?SELECT @USERNAME = INSERTED.username FROM INSERTED- 这是不确定的。您需要重写触发器以考虑到这一点! -
你也可以提供程序的sql脚本或者至少是程序的签名吗?
-
@marc_s 在我的项目中,当时只插入了一个用户,您一次不能创建多个用户。但我可以重写它以防万一。此外,这不是我的问题(至少现在是这样),因为它可以使用没有点的用户名运行。
标签: sql-server database stored-procedures login triggers