在 Advantage Database Server 中实现唯一的代理键

Implementing a unique surrogate key in Advantage Database Server

我最近接管了一个使用 Advantage Database Server 作为后端的系统的支持。对于某些背景,我有多年的数据库经验,但直到现在才使用过 ADS,所以我的问题纯粹是关于如何在这个特定的 DBMS 中实现标准模式。

有一个以前开发的存储过程以这种方式管理 ID 列:

@ID = (SELECT ISNULL(MAX(ID), 0) FROM ExampleTable);
@ID = @ID + 1;

INSERT INTO Example_Table (ID, OtherStuff)
VALUES (@ID, 'Things');

--Do some other stuff.

UPDATE ExampleTable
SET AnotherColumn = 'FOO'
WHERE ID = @ID;

我的问题是我现在需要运行 这个存储过程并行多次。可以想象,当我这样做时,相同的 ID 值被多次抓取。

我需要的是一种始终如一地创建唯一值的方法,即使我在同一时刻多次 运行 存储过程,我也可以确保该值是唯一的。在 SQL 服务器中,我可以创建一个名为 ID 的 IDENTITY 列,然后执行以下操作:

INSERT INTO ExampleTable (OtherStuff)
VALUES ('Things');

SET @ID = SCOPE_IDENTITY(); 

ADS 有 autoinc,这看起来很相似,但我找不到任何最终告诉我如何以我可以 100% 确定的方式 return 新创建的值的值在并发使用下将是正确的。 ADS 开发人员指南实际上警告我不要使用 autoinc,在线帮助文​​件提供的功能似乎可以检索最后生成的 autoinc ID(这不是我想要的 - 我想要由前一个语句创建的那个,不是所有会话中创建的最后一个)。帮助文件还列出了这些函数,并警告它们在涉及并发的情况下可能无法正常工作。

我如何在 ADS 中实现它?我应该使用 autoinc,我不知道的其他一些内置方法,还是我真的需要按照开发人员指南的建议去做,并在尝试插入 [=31= 之前生成我的唯一标识符] 首先?如果我应该使用autoinc,我如何获取刚刚插入到table中的值?

您将 LastAutoInc(STATEMENT)autoinc 一起使用。

来自documentation(在优势SQL->支持的SQL语法->支持的标量函数->杂项下):

LASTAUTOINC(CONNECTION|STATEMENT)

Returns the last used autoinc value from an insert or append. Specifying CONNECTION will return the last used value for the entire connection. Specifying STATEMENT returns the last used value for only the current SQL statement. If no autoinc value has been updated yet, a NULL value is returned.

Note: Triggers that operate on tables with autoinc fields may affect the last autoinc value.

Note: SQL script triggers run on their own SQL statement. Therefore, calling LASTAUTOINC(STATEMENT) inside a SQL script trigger would return the lastautoinc value used by the trigger's SQL statement, not the original SQL statement which caused the trigger to fire. To obtain the last original SQL statement's lastautoinc value, use LASTAUTOINC(CONNECTION) instead.

Example: SELECT LASTAUTOINC(STATEMENT) FROM System.Iota

另一种选择是使用 GUID。

(我不确定,但是当你说 时你可能已经暗示了这一点“或者我真的需要按照开发人员指南的建议去做,并在尝试之前生成我的唯一标识符首先插入 table。“ - 抱歉,但此信息可能对其他人有用 :) )

使用 GUID 作为代理键允许应用程序或数据库创建一个唯一标识符,a guarantee of no clashes

Advantage 12 内置了对 GUID 数据类型的支持:

GUID and 64-bit Integer Field Types

Advantage server and clients now support GUID and Long Integer (64-bit) data types in all table formats. The 64-bit integer type can be used to store integer values between -9,223,372,036,854,775,807 and 9,223,372,036,854,775,807 with no loss of precision. The GUID (Global Unique Identifier) field type is a 16-byte data structure. A new scalar function NewID() is available in the expression engine and SQL engine to generate new GUID. See ADT Field Types and Specifications and DBF Field Types and Specifications for more information.

http://scn.sap.com/docs/DOC-68484

对于早期版本,您可以将 GUID 存储为 char(36)。 (当然,请考虑您的 performance 要求。)然后您需要在应用程序层中在 GUID 和字符串之间来回进行一些转换。如果您正在使用一些中间数据访问层,例如NHibernate 或 Entity Framework,您至少应该能够将转换本地化到一个地方。

如果您的逻辑的某些部分在存储过程中,您应该能够使用 newid()newidstring() 函数,具体取决于支持列的类型:

INSERT INTO Example_Table (newid(), OtherStuff)