简化使用 NEWSEQUNETIALID() 列默认值的 SQL 插入
我有以下插入存储过程:
CREATE Procedure dbo.APPL_ServerEnvironmentInsert
(
@ServerEnvironmentName varchar(50),
@ServerEnvironmentDescription varchar(1000),
@UserCreatedId uniqueidentifier,
@ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
-- Stores the ServerEnvironmentId.
DECLARE @APPL_ServerEnvironment TABLE (ServerEnvironmentId uniqueidentifier)
-- If @ServerEnvironmentId was not supplied.
IF (@ServerEnvironmentId IS NULL)
BEGIN
-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
OUTPUT Inserted.ServerEnvironmentId INTO @APPL_ServerEnvironment
VALUES
(
@ServerEnvironmentName,
@ServerEnvironmentDescription,
GETDATE(),
@UserCreatedId
)
-- Get the ServerEnvironmentId.
SELECT @ServerEnvironmentId = ServerEnvironmentId
FROM @APPL_ServerEnvironment
END
ELSE
BEGIN
-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentId,
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
VALUES
(
@ServerEnvironmentId,
@ServerEnvironmentName,
@ServerEnvironmentDescription,
GETDATE(),
@UserCreatedId
)
END
GO
我可以将上面的内容简化为:
CREATE Procedure dbo.APPL_ServerEnvironmentInsert
(
@ServerEnvironmentName varchar(50),
@ServerEnvironmentDescription varchar(1000),
@UserCreatedId uniqueidentifier,
@ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
-- Ensure @ServerEnvironmentId IS NOT NULL
SELECT ISNULL(@ServerEnvironmentId, newid())
-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentId,
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
VALUES
(
@ServerEnvironmentId,
@ServerEnvironmentName,
@ServerEnvironmentDescription,
GETDATE(),
@UserCreatedId
)
GO
但通过这样做,我失去了 newsequentialid()
相对于 newid().
的性能改进。 newsequentialid()
不能在代码中设置为 newid()
,它只能作为表列级别的默认值提供。
有人对简化原始查询但利用newsequentialid()有什么想法吗?或者,原始查询是实现此目的的最简单的解决方案吗?
I have the following insert stored procedure:
CREATE Procedure dbo.APPL_ServerEnvironmentInsert
(
@ServerEnvironmentName varchar(50),
@ServerEnvironmentDescription varchar(1000),
@UserCreatedId uniqueidentifier,
@ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
-- Stores the ServerEnvironmentId.
DECLARE @APPL_ServerEnvironment TABLE (ServerEnvironmentId uniqueidentifier)
-- If @ServerEnvironmentId was not supplied.
IF (@ServerEnvironmentId IS NULL)
BEGIN
-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
OUTPUT Inserted.ServerEnvironmentId INTO @APPL_ServerEnvironment
VALUES
(
@ServerEnvironmentName,
@ServerEnvironmentDescription,
GETDATE(),
@UserCreatedId
)
-- Get the ServerEnvironmentId.
SELECT @ServerEnvironmentId = ServerEnvironmentId
FROM @APPL_ServerEnvironment
END
ELSE
BEGIN
-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentId,
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
VALUES
(
@ServerEnvironmentId,
@ServerEnvironmentName,
@ServerEnvironmentDescription,
GETDATE(),
@UserCreatedId
)
END
GO
I could have simplified the above as:
CREATE Procedure dbo.APPL_ServerEnvironmentInsert
(
@ServerEnvironmentName varchar(50),
@ServerEnvironmentDescription varchar(1000),
@UserCreatedId uniqueidentifier,
@ServerEnvironmentId uniqueidentifier OUTPUT
)
WITH RECOMPILE
AS
-- Ensure @ServerEnvironmentId IS NOT NULL
SELECT ISNULL(@ServerEnvironmentId, newid())
-- Insert the data into the table.
INSERT INTO APPL_ServerEnvironment WITH(TABLOCKX)
(
ServerEnvironmentId,
ServerEnvironmentName,
ServerEnvironmentDescription,
DateCreated,
UserCreatedId
)
VALUES
(
@ServerEnvironmentId,
@ServerEnvironmentName,
@ServerEnvironmentDescription,
GETDATE(),
@UserCreatedId
)
GO
But by doing so, i loose the performance improvements of the newsequentialid()
over newid().
newsequentialid()
can not be set in code as newid()
, it can only be supplied as a default value on a table column level.
Any ideas anyone on simplifying the original query, but utilising newsequentialid()
? Or, is the original query the most simplified solution in achieving this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于
newsequentialid()
只能用作列默认值,因此您可以将原始查询更改为:如果没有值,则仅插入
@ServerEnvironmentId
提供,从而生成一个新的顺序 ID 并从OUTPUT
子句中检索它,
然后更新由最初传入的
@ServerEnvironmentId
定义的行,或者通过插入“刚刚创建的新 ID”虚拟行”到表中,
不确定如果那会更快/更有效 - 你将不得不对此进行一些测量。
Since the
newsequentialid()
can only be used as a column default value, you could change your original query to:insert just the
@ServerEnvironmentId
if no value had been supplied, thus generating a new sequential ID and retrieving it from theOUTPUT
clausethen update that row defined by either the
@ServerEnvironmentId
passed in originally, or the new ID you just created by inserting a "dummy row" into your tableNot sure if that would be any faster / more efficient - you would have to do some measurements on that.
是的。考虑尝试一下新合并语句。它应该与 newsequentialid() 的列默认值 100% 兼容,并且它将 SQL 简化为单个简洁的语句。我希望这有帮助。
Yes. Consider giving the new merge statement a try. It should be 100% compatible with the column default of newsequentialid(), and it will get the SQL down to a single concise statement. I hope this helps.
我原来的想法是正确的。这是最简单且最具可读性的解决方案。
My original idea was correct. It is the simplest and most readable solution possible.