我正在使用没有自动递增标识列的数据库(iSeries)。因此,我必须在应用程序中即时生成ID。
我有一个用户定义的函数可以为我完成这个,因为我需要为几个表生成这些ID:
<cffunction name="getNewTableId" returntype="numeric" output="false">
<cfargument name="TableName" type="string" required="true" />
<cfargument name="ColumnName" type="string" required="true" />
<cfargument name="SeedNum" type="numeric" required="false" default="1" />
<cfquery name="qMaxId" datasource="#REQUEST.DSN#">
SELECT MAX(#ARGUMENTS.ColumnName#) AS Id
FROM #ARGUMENTS.TableName#
</cfquery>
<cfscript>
if (qMaxId.RecordCount && IsValid("integer", qMaxId.Id))
return qMaxId.Id + 1;
return ARGUMENTS.SeedNum;
</cfscript>
</cffunction>
(我知道这不是很安全,但现在只是为了让它在开发环境中工作,这是非常简单的。)
我的问题是,在INSERT语句中调用函数有什么好处/缺点,而不是在本地保存ID值:
在INSERT语句中生成ID
<cfquery datasource="#REQUEST.DSN#">
INSERT INTO MyTable
(
ID,
NameTxt
)
SELECT #getNewTableId('MyTable','ID')#,
<cfqueryparam
value="#FORM.MyName#"
cfsqltype="CF_SQL_VARCHAR"
maxlength="20" />
</cfquery>
在INSERT语句之前生成ID
<cfset newId = getNewTableId('MyTable','ID') />
<cfquery datasource="#REQUEST.DSN#">
INSERT INTO MyTable
(
ID,
NameTxt
)
SELECT #newId#,
<cfqueryparam
value="#FORM.MyName#"
cfsqltype="CF_SQL_VARCHAR"
maxlength="20" />
</cfquery>
我倾向于倾向于第一个选项,因为ColdFusion将准备语句并立即执行它,而不是在本地存储值,然后让ColdFusion准备SQL语句。
有什么不同吗?
答案 0 :(得分:1)
AS / 400支持使用列定义上的GENERATED ... AS IDENTITY
自动递增标识列。
有关详细信息,请参阅SQL Reference: CREATE TABLE声明。
答案 1 :(得分:0)
无论哪种方式,你似乎都有可能重复。
让我们说两个用户同时执行相同的操作,并且获取max id的查询需要500ms(很长时间,但是出于示例目的),这将不可避免地创建重复的id。两种解决方案:
至于将id作为变量存储或者不存在更好是一个更好的问题,“我是否会在此请求中的任何时候使用此ID?”