根据不存在和不同标准插入数据
Insert data based on non existence and different criteria's
我试图仅在两种情况下向我的 table 添加一行,但是当插入它时检索错误,我无法弄清楚
Create PROC [dbo].[setvisitorqueue]
@pid bigint = null , @vid int = NULL ,@regdate nvarchar(50) =NULL
AS
declare @queNum int =null
set @queNum = (select max([ticketNo]) + 1 from [dbo].[queue] where [ticketdate]= GetDate())
if( @queNum is null) begin set @queNum=1 end
Declare @Tktt int = null
set @Tktt = (select count(queue.ticketid) from queue where (queue.pid = @pid )and (queue.ticketdate = GetDate()) and (queue.vid = @vid and queue.checked = 0))
if (@Tktt is null )
begin insert into queue (vid , pid , ticketNo , ticketdate ) Values (@Vid,@pid,@queNum,@regdate ) end
它不适合我。
你能试试这样简单的方法吗?
CREATE PROC [dbo].[setvisitorqueue]
@pid BIGINT = null,
@vid INT = NULL,
@regdate NVARCHAR(50) = NULL
AS
IF (
SELECT COUNT(ticketid)
FROM [dbo].[queue]
WHERE checked = 0 and pid = @pid and vid = @vid and ticketdate = GetDate()
) = 0
INSERT INTO [dbo].[queue](vid pid, ticketdate, ticketNo )
SELECT @Vid, @pid, @regdate, ticketNo = IsNull(MAX([ticketNo]),0) + 1
FROM [dbo].[queue]
WHERE [ticketdate]= GetDate();
RETURN;
GO
在这段代码中,我完成了以下操作:
- 改进了大写、意向、空格等的可读性
- 已消除的变量 - 您在该代码中不需要它们 您不需要
如果不使用,需要在开始时计算一个“TicketNo”。
因此,如果需要,将在 IF 语句中计算。
- 您不需要在每笔交易中都使用 BEGIN-END,单个
请求是一个交易
不确定您的错误是什么,但是您的程序不会执行任何操作,因为当您“计算”它时 returns 一个数字。这意味着您的“@Tktt”变量永远不会为 NULL。
我猜您的意图是 运行 在未找到任何记录时插入语句并将“COUNT”查询与“0”值进行比较。
这是您的 SP,其中包含我发现的所有问题,并通过评论进行了更正,并添加了最佳实践。正如另一个答案所指出的,您可能可以简化事情。我只是为了纠正现有的问题。
-- NOTES: Keep your casing and layout consistent
-- Always terminate statements with a semi-colon
-- Don't add un-necessary brackets, they just clutter the code
-- You also have a concurrency issue:
-- if this proc is called twice at the same time you could issue the same ticket number twice
create proc [dbo].[setvisitorqueue]
(
@pid bigint = null,
@vid int = null,
-- Only every use a datetime/date datatype to store a datatime/date. Datetime2 is the current standard. Change precision to suit.
@regdate datetime2(0) = null
)
as
begin
-- Always start your SP with
set nocount, xact_abort on;
declare @queNum int = null;
set @queNum = (
select max([ticketNo]) + 1
from dbo.[queue]
-- This seems very unlikely to happen? It has to match down to the fraction of a second.
where [ticketdate] = getdate()
);
if @queNum is null begin
set @queNum = 1;
end;
declare @Tktt int = null;
-- @Tktt will *never* be null after this, it may be zero though.
set @Tktt = (
select count(*)
from dbo.[queue]
where pid = @pid
-- This seems very unlikely to happen? It has to match down to the fraction of a second.
and ticketdate = getdate()
and vid = @vid and checked = 0
);
-- Handle 0 or null just in case
-- if @Tktt is null -- THIS IS WHAT PREVENTED YOUR INSERT
if coalesce(@Tktt,0) = 0
begin
insert into dbo.[queue] (vid, pid, ticketNo, ticketdate)
values (@Vid, @pid, @queNum, @regdate);
end;
-- Always return the status of the SP, 0 means OK
return 0;
end;
我试图仅在两种情况下向我的 table 添加一行,但是当插入它时检索错误,我无法弄清楚
Create PROC [dbo].[setvisitorqueue]
@pid bigint = null , @vid int = NULL ,@regdate nvarchar(50) =NULL
AS
declare @queNum int =null
set @queNum = (select max([ticketNo]) + 1 from [dbo].[queue] where [ticketdate]= GetDate())
if( @queNum is null) begin set @queNum=1 end
Declare @Tktt int = null
set @Tktt = (select count(queue.ticketid) from queue where (queue.pid = @pid )and (queue.ticketdate = GetDate()) and (queue.vid = @vid and queue.checked = 0))
if (@Tktt is null )
begin insert into queue (vid , pid , ticketNo , ticketdate ) Values (@Vid,@pid,@queNum,@regdate ) end
它不适合我。
你能试试这样简单的方法吗?
CREATE PROC [dbo].[setvisitorqueue]
@pid BIGINT = null,
@vid INT = NULL,
@regdate NVARCHAR(50) = NULL
AS
IF (
SELECT COUNT(ticketid)
FROM [dbo].[queue]
WHERE checked = 0 and pid = @pid and vid = @vid and ticketdate = GetDate()
) = 0
INSERT INTO [dbo].[queue](vid pid, ticketdate, ticketNo )
SELECT @Vid, @pid, @regdate, ticketNo = IsNull(MAX([ticketNo]),0) + 1
FROM [dbo].[queue]
WHERE [ticketdate]= GetDate();
RETURN;
GO
在这段代码中,我完成了以下操作:
- 改进了大写、意向、空格等的可读性
- 已消除的变量 - 您在该代码中不需要它们 您不需要 如果不使用,需要在开始时计算一个“TicketNo”。 因此,如果需要,将在 IF 语句中计算。
- 您不需要在每笔交易中都使用 BEGIN-END,单个 请求是一个交易
不确定您的错误是什么,但是您的程序不会执行任何操作,因为当您“计算”它时 returns 一个数字。这意味着您的“@Tktt”变量永远不会为 NULL。
我猜您的意图是 运行 在未找到任何记录时插入语句并将“COUNT”查询与“0”值进行比较。
这是您的 SP,其中包含我发现的所有问题,并通过评论进行了更正,并添加了最佳实践。正如另一个答案所指出的,您可能可以简化事情。我只是为了纠正现有的问题。
-- NOTES: Keep your casing and layout consistent
-- Always terminate statements with a semi-colon
-- Don't add un-necessary brackets, they just clutter the code
-- You also have a concurrency issue:
-- if this proc is called twice at the same time you could issue the same ticket number twice
create proc [dbo].[setvisitorqueue]
(
@pid bigint = null,
@vid int = null,
-- Only every use a datetime/date datatype to store a datatime/date. Datetime2 is the current standard. Change precision to suit.
@regdate datetime2(0) = null
)
as
begin
-- Always start your SP with
set nocount, xact_abort on;
declare @queNum int = null;
set @queNum = (
select max([ticketNo]) + 1
from dbo.[queue]
-- This seems very unlikely to happen? It has to match down to the fraction of a second.
where [ticketdate] = getdate()
);
if @queNum is null begin
set @queNum = 1;
end;
declare @Tktt int = null;
-- @Tktt will *never* be null after this, it may be zero though.
set @Tktt = (
select count(*)
from dbo.[queue]
where pid = @pid
-- This seems very unlikely to happen? It has to match down to the fraction of a second.
and ticketdate = getdate()
and vid = @vid and checked = 0
);
-- Handle 0 or null just in case
-- if @Tktt is null -- THIS IS WHAT PREVENTED YOUR INSERT
if coalesce(@Tktt,0) = 0
begin
insert into dbo.[queue] (vid, pid, ticketNo, ticketdate)
values (@Vid, @pid, @queNum, @regdate);
end;
-- Always return the status of the SP, 0 means OK
return 0;
end;