我的汽车数量有2个部分SQL语句从数据库
3位是序列号,最后8位是年份和月份发票
。例如:001072013
所以,如果我想下一个InvoiceNo
我从数据库这样
发票号码的最后一个条目选择削减前3位,并进行增量,并结合发票
所以的月和年这将是002072013
的问题是上面的语句不返回最后一项的值
和升降都不起作用
我的汽车数量有2个部分SQL语句从数据库
3位是序列号,最后8位是年份和月份发票
。例如:001072013
所以,如果我想下一个InvoiceNo
我从数据库这样
发票号码的最后一个条目选择削减前3位,并进行增量,并结合发票
所以的月和年这将是002072013
的问题是上面的语句不返回最后一项的值
和升降都不起作用
我会尝试:
select TOP 1 InvoiceNo
from BuyInvoice order by right(InvoiceNo,4) desc,
right(InvoiceNo, 6) desc,
InvoiceNo desc
试试这个
select TOP 1 InvoiceNo
from BuyInvoice order by InvoiceNo desc
如果您有以下发票:'001071913','002071913','001072013'那么这个解决方案返回'002071913'这是因为最后一张发票是07/20/13(mm/dd/yy),所以错误。 –
我认为BuyInvoice
表有InvoiceDate
列有一个像InvoiceNo
列date
部分相同的值。在这种情况下我会使用(该溶液是未测试):
DECLARE @InvoiceDate DATE;
SET @InvoiceDate='2013-07-20';
BEGIN TRANSACTION;
DECLARE @LastInvoiceNo VARCHAR(9);
SELECT TOP(1) @LastInvoiceNo=bi.InvoiceNo
-- This table hint (UPDLOCK) take a U lock on this row[s] so any concurrent [similar] transactions will have to wait till this transaction is finished
-- This will prevent duplicated new InvoiceNo
FROM dbo.BuyInvoice bi WITH(UPDLOCK)
WHERE [email protected]
ORDER BY bi.InvoiceNo DESC;
DECLARE @Seq SMALLINT;
SET @Seq=ISNULL(CONVERT(SMALLINT,LEFT(@LastInvoiceNo,3)),0);
SET @[email protected]+1;
DECLARE @NewInvoiceNo VARCHAR(9);
SET @NewInvoiceNo=RIGHT('00'+CONVERT(VARCHAR(3),@Seq),3)+STUFF(STUFF(CONVERT(VARCHAR(10),@InvoiceDate,101),3,1,''),5,1,''); -- Convert style 101 = mm/dd/yyyy
...
INSERT dbo.BuyInvoice(InvoiceNo,InvoiceDate,...)
VALUES (@NewInvoiceNo,@InvoiceDate,...);
...
COMMIT TRANSACTION;
此外,我会用BEGIN TRY ... END CATCH
拦截例外,如果需要回滚此事务(link:实施例B)。
而且,我将创建下列指标:
-- This way, the InvoiceNo column will have uniques values
CREATE UNIQUE INDEX IUN_BuyInvoice_InvoiceNo
ON dbo.BuyInvoice(InvoiceNo);
GO
-- This index is used by SELECT TOP(1) ... query
CREATE UNIQUE INDEX IN_BuyInvoice_InvoiceDate_InvoiceNo
ON dbo.BuyInvoice(InvoiceDate,InvoiceNo);
GO
注意:如果您没有'InvoiceDate'列,那么您可以添加一个计算列:'ALTER TABLE dbo.BuyInvoice ADD InvoiceDate AS(CONVERT(DATE,STUFF(STUFF(RIGHT(InvoiceNo,6),3,0 ,'/'),6,0,'/ 20'),101));';这个计算列没有被持久化,因此除了(当然)'IUN_BuyInvoice_InvoiceDate_InvoiceNo'索引之外,不会消耗堆/聚集索引中的额外存储空间。 –
注意:在SET @ Seq = @Seq + 1后,我会加上这个检查IF @Seq> 999
RAISERROR('@ Seq exhausted',16,1);
END;'。 –
尝试
select top 1 InvoiceNo from BuyInvoice order by left(InvoiceNo,3) desc
为了保存自己很多的麻烦,实现你的表中的列invoicedate。 –
这是您需要使用的遗留数据库还是您拥有设计控制的数据库?这里的方法是非常老式的传统方法,远非今天的最佳实践。 – Tim
只是一个侧面说明:在我看来,你会用尽相当快的序列号,因为三位数字只能表示0-999。我会认真考虑将序列作为一个单独的列允许更高的增长,并使用存储过程或视图构建InvoiceNo。 – jpw