是否可能有一个非null列,其中通过调用存储过程(其参数是传递给插入行的值)的存储过程在插入时生成值?
例如,我有表User
:
| username | name | surname | id |
插入看起来像这样:
INSERT INTO USER (username, name, surname)
VALUES ('myusername', 'myname', 'mysurname');
在id
列中填充了一个(整数)值,该值是通过使用参数mystoredproc
,myusername
,myname
调用存储过程mysurname
来检索的。
另一个问题是,该存储过程是在每一行上调用还是以分组的方式调用?例如,我希望存储过程采用name
并在其中附加一个随机整数,这样,如果我插入100个名称为“ David”的用户,他们将得到相同的id
并且存储过程将仅被调用一次。第二点有点不好的例子。
答案 0 :(得分:2)
美好的一天,
是否可能有一个非null列,其中通过调用存储过程在插入时生成值
选项1:请检查是否适合您
**可能不需要使用外部SP,但是如果需要,您可以从触发器执行SP
**触发器执行的所有操作与原始查询都在同一事务中。
是否将在每一行上调用此存储过程
不!对于您在同一条语句中插入的所有行,触发器将一次执行。插入的表包括所有已插入的行。在更新部分(第4步)中,您可以更新插入一次的所有行,而无需为每行执行某些操作
**如果您确实使用从触发器执行的外部SP,则可以将所有插入的表作为一个using Table-Valued Parameter
传递给它。-------------------更新---------------
以下是使用此逻辑的完整示例:
drop table if exists T;
CREATE TABLE T (id int identity(2,2), c int NOT NULL default 1)
GO
CREATE TRIGGER tr ON T AFTER INSERT
AS BEGIN
SET NOCOUNT ON;
UPDATE T SET T.c = T2.C + 1
FROM inserted T2
INNER JOIN T T1 ON T1.id = T2.id
END
INSERT T(c) values (1) -- I insert the value 1 but the trigger will change it to 1+1=2
select * from T
GO
-- test multiple rows:
INSERT T(c) values (10),(20),(30),(40)
select * from T
GO
答案 1 :(得分:-1)
DECLARE @rc INT = 0,
@UserID INT = ABS(CHECKSUM(NEWID())) % 1000000 + 1;
WHILE @rc = 0
BEGIN
IF NOT EXISTS (SELECT 1 FROM dbo.Users WHERE UserId= @UserId)
BEGIN
INSERT dbo.Users(UserId) WHERE Username = @UserName SELECT @UserId;
SET @rc = 1;
END
ELSE
BEGIN
SELECT @UserId = ABS(CHECKSUM(NEWID())) % 1000000 + 1,
@rc = 0;
END
END