C# 如何获取具有特定要求的数据库表中的最后一行?
好的,我在我的网站上接受付款(通过Authorize.Net)。付款表单重定向到收据页面C# 如何获取具有特定要求的数据库表中的最后一行?,c#,sql-server,database,C#,Sql Server,Database,好的,我在我的网站上接受付款(通过Authorize.Net)。付款表单重定向到收据页面 我将在数据库中有一列发票代码(列InvoiceCode),在本例中为RRC0A。然后我将有另一个8位数字的列(列InvoiceNumber)。然后我将有InvoiceCode+InvoiceNumber=InvoiceId。例如,InvoiceId将是RRC0A+8个数字。它将按如下方式递增:00000000、00000001、00000002等。因此,InvoiceId将为RRC0A00000001。我不
我将在数据库中有一列发票代码(列InvoiceCode),在本例中为RRC0A。然后我将有另一个8位数字的列(列InvoiceNumber)。然后我将有InvoiceCode+InvoiceNumber=InvoiceId。例如,InvoiceId将是RRC0A+8个数字。它将按如下方式递增:00000000、00000001、00000002等。因此,InvoiceId将为RRC0A00000001。我不能简单地增加数据库中的列,因为还有其他的InvoiceCodes也从00000000开始
至于如何在sql中左键填充,请查看此项。一列中的As只是一个糟糕的设计 有复合PK
InvCode(varchar),InvInt(int) isnull将处理第一个 一个语句就是一个事务,所以我认为两个同时出现的语句不会破坏
即使他们这样做了,PK也会被违反,因此插入将失败 对格式化发票编号使用视图或计算列
CREATE TABLE [dbo].[Invoice](
[InvCode] [varchar](10) NOT NULL,
[InvInt] [int] NOT NULL,
[Formatted] AS ([InvCode]+right('00000000'+CONVERT([nvarchar](10),[InvInt]),(8))),
CONSTRAINT [PK_Invoice] PRIMARY KEY CLUSTERED
(
[InvCode] ASC,
[InvInt] ASC
)
使用标识和计算列,可以在插入时创建格式正确的发票编号
CREATE TABLE [dbo].[Invoices](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Code] [nchar](5) NOT NULL,
[InvoiceNumber] AS ([Code]+right('00000000'+CONVERT([nvarchar](10),[ID]),(8))) PERSISTED,
[Cost] [decimal](18, 2) NOT NULL,
CONSTRAINT [PK_Invoices] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
)
批量插入样品
INSERT INTO [dbo].[Invoices] ([Code], [Cost])
OUTPUT INSERTED.*
SELECT 'ABC01', 500 UNION ALL
SELECT 'ABC01', 501 UNION ALL
SELECT 'EFG23', 502 UNION ALL
SELECT 'RRAc1', 503 UNION ALL
SELECT 'ABC01', 504
输出
ID Code InvoiceNumber Cost
1 ABC01 ABC0100000001 500.00
2 ABC01 ABC0100000002 501.00
3 EFG23 EFG2300000003 502.00
4 RRAc1 RRAc100000004 503.00
5 ABC01 ABC0100000005 504.00
插入记录时,您可以同时获取ID和InvoiceNumber
这些值也会被持久化,因此它们可以像其他列一样被索引。我建议使用标识字段和计算字段。不要试图选择最后插入的行,因为这样会出错。处理连续id通常是一个非常糟糕的主意,最好在数据库上创建一个自动递增字段。甚至不要假装自己管理递增的数字是一个好主意。这就是identity属性的设计目的。另一个选择是序列。这两种方法都可以处理并发和回滚事务,这两种方法都很难做到正确,也很容易出错。谢谢,我以前没有听说过序列。我同意自动递增会更好,但是,在我有很多InvoiceCode要处理的情况下,它将不起作用。如果我这样做的话,我将不得不用一堆自动递增的列来填充表。请确保在InvoiceCode+InvoiceNumberDon上抛出一个唯一的索引,除非您使用Scope_Identity()执行where操作而您的主键.Scope_标识只有在选择与最近的插入发生在同一查询上下文中时才有用。如果您没有从插入中获得想法,则无法确保您获得正确的发票。如果您只选择最后一行,是否可能在您的请求之前插入了另一张发票。好吧,按照我阅读原始问题的方式,如果插入了另一张发票,则OP希望在其结果中插入该发票。用他的话来说:“我怎样才能获取输入数据库的最后一个发票号码?”我理解你的意思,但我认为你误解了这个问题。许多人提出的问题都是基于错误的假设。最好在他们以后发现错误之前帮助他们修复错误。谢谢,这可以奏效。我担心如果两个人同时填写付款单会发生什么情况?在这种情况下,SQL查询本身是安全的,当select运行时,表上会有一个读锁,这将阻止更新。您仍然需要处理上游数据不同步的问题。这只是许多不必要的读锁和MAX(InvoiceID),因为您知道InvoiceCode“我不能简单地增加数据库中的列,因为还有其他的InvoiceCode也从00000000开始”。我的理解是OP希望每个发票代码的发票号从0开始。是的,这是正确的。如果我使用此代码,我必须为每个InvoiceCode创建一个表。现在有几十个InvoiceCodes,它只会在时间上扩展。你可以在组更新中用一行来完成,但我不会推荐它。您最好只使用所需代码替换前缀,但使用带有标识的发票号。如果您尝试将更新外部化,那么以后在保持值同步方面会遇到更多问题。(您可以轻松地将前缀移动到表中的另一列,并将其用作计算值的一部分。如果您执行类似于关节的操作来获取代码,则将无法使用持久值。)我将尝试此操作。我想这对我有用。
INSERT INTO [dbo].[Invoices] ([Code], [Cost])
OUTPUT INSERTED.*
SELECT 'ABC01', 500 UNION ALL
SELECT 'ABC01', 501 UNION ALL
SELECT 'EFG23', 502 UNION ALL
SELECT 'RRAc1', 503 UNION ALL
SELECT 'ABC01', 504
ID Code InvoiceNumber Cost
1 ABC01 ABC0100000001 500.00
2 ABC01 ABC0100000002 501.00
3 EFG23 EFG2300000003 502.00
4 RRAc1 RRAc100000004 503.00
5 ABC01 ABC0100000005 504.00