在我的表中,这个值在字段transectionNO就像这样
R1000891
R1000892
R1000893
....
。我希望最后一笔交易不是R1000893
,而不是R
。所以我可以添加R + last transactionNo + 1
来创建新的transectionNo。
我使用下面的查询,但有时此查询给出旧值,因此它是创建错误。
DECLARE @trnsectionNo varchar(50) ,
@RoundTotal varchar(50) ,
@transactionNo varchar(50)
SELECT top 1 @trnsectionNo = trans_no from Item_Receive ORDER BY trans_no DESC
SET @trnsectionNo= Substring(@trnsectionNo,2,10)
SET @RoundTotal= (ISNULL(@trnsectionNo,0) + 1)
SET @transactionNoNew = 'R'+@RoundTotal
感谢您的帮助。
答案 0 :(得分:1)
您遇到的问题是您没有将数字转换为int,因此SQL Server无法执行+1。这就是你应该做的事情:
DECLARE @trnsectionNo varchar(50) ,
@transactionNoNew varchar(50)
SELECT top 1 @trnsectionNo = trans_no from Item_Receive ORDER BY trans_no DESC
if (@@rowcount = 0) set @trnsectionNo = 'R0'
select @transactionNoNew = 'R'+convert(varchar(10), convert(int, Substring(@trnsectionNo,2,10)) + 1)
如果您需要在数字中加零,例如R000001而不是R1,那么您需要添加更多逻辑。
答案 1 :(得分:1)
请尝试此查询。我还为演示创建了一个小提琴: http://sqlfiddle.com/#!6/e928b/6
请注意,我所做的更改只包括将子字符串转换为INT
并在其上应用MAX
。
DECLARE @trnsectionNo INT ,
@RoundTotal varchar(50) ,
@transactionNoNew varchar(50)
SELECT @trnsectionNo = MAX(CAST(Substring(@trnsectionNo,2,10)AS INT)) from Item_Receive
SET @RoundTotal= (ISNULL(@trnsectionNo,0) + 1)
SET @transactionNoNew = 'R'+@RoundTotal
答案 2 :(得分:0)
尝试使用Stuff
select top 1 @trnsectionNo = trans_no from Item_Receive order by Stuff(trans_no,1,1,'') desc
答案 3 :(得分:0)
我写这个作为答案,因为评论太长了。
此处的其他答案将告诉您如何通过将varchar转换为int来解决问题。它们在你提出的问题范围内是正确的,实质上是“我如何使这段非常不安全的代码工作(大部分时间)?”
为什么我说您的代码不安全?原子性!如果您对查询进行两次调用,则会得到重复的数字。请在此处阅读有关原子性和相关概念的内容:http://searchsqlserver.techtarget.com/definition/ACID它们对于编写安全的数据库代码至关重要!
如果你想继续使用你拥有的代码,并且为了让自己安全起来给自己一个艰难的生活,你需要将整个事情包装在一个事务中并对你的表进行锁定。该交易还需要包含您的新ID号的后续插入,但不包含在您的代码段中。
但是为什么还要使用varchar来保存顺序交易号?如果您需要在前面显示“R”,那么应该在您的UI代码中。
如果您希望安全代码具有原子性和简单生命,只需使用带有标识属性的int列。有关详细信息,请参阅此处:http://www.sqlteam.com/article/understanding-identity-columns
如果您需要将新ID值返回到您的应用,请使用SCOPE_IDENTITY()函数:https://msdn.microsoft.com/en-gb/library/ms190315(v=sql.110).aspx