【问题标题】:Teradata identity column and "Duplicate unique prime key error in dbname.tablename"Teradata 标识列和“dbname.tablename 中的重复唯一主键错误”
【发布时间】:2012-07-28 12:04:25
【问题描述】:

我使用以下定义为 Teradata 标识列创建了一个表:

默认生成的 ID 整数作为身份 (从 1 开始 增加 1 最小值 0 最大值 100000000 无循环), ---- 唯一主索引 (ID)

几个月来,ID 列一直正常工作,自动为该列生成唯一值。然而,在过去的一个月里,ELMAH间歇性地从我们的 .NET 4.0 ASP.NET 应用程序中报告以下异常:

Teradata.Client.Provider.TdException: [Teradata Database] [2801] Duplicate unique prime key error in DATABASENAME.TABLENAME.

我能够通过打开 SQL 助手并使用原始 SQL 将一堆记录插入到表中来复制它。不出所料,大多数时候它会插入成功,但其他时候它会抛出上述异常。

出现此错误的原因似乎是 Teradata 正在尝试为其先前生成的该列生成一个值。

有没有人知道如何弄清正在发生的事情的真相?至少,我想要一些方法来更深入地调试问题。

【问题讨论】:

    标签: unique identity teradata


    【解决方案1】:

    我建议将标识列的定义更改为GENERATED ALWAYS,以防止应用程序或 ETL 进程提供可能已使用的值。事实上,Teradata 建议,如果您将 IDENTITY 列用作 UPI 的一部分,则应将其定义为 GENERATED ALWAYS ... NO CYCLE

    编辑:

    如果您的业务要求必须能够提供一个值,我也会考虑使用超出您为 IDENTITY 列预留的值范围的域。您可以使用比 IDENTITY 列高一个数量级的负域或范围。个人偏好是使用否定域。

    【讨论】:

    • generated always 不会阻止您将自己的值插入标识列吗?出于简单起见,我不会解释的原因,我需要能够在插入新记录时为该字段指定我自己的值,从而覆盖 Teradata 本身分配值的行为。当我希望数据库为我生成它时,我只是不在插入语句中包含字段名称。
    • 当您遇到此错误时,您是在原始 SQL 中为 UPI 提供值,还是依靠 Teradata 为您生成身份值?
    • 在这种情况下,我依靠 Teradata 来生成值。这意味着我将使用insert into mydb.employee (name, email) values ('bob', 'bob@blob.com') 而不是insert into mydb.employee (id, name, email) values (100, 'bob', 'bob@blob.com')。大概从今年 2 月左右开始,这一切就一直在发挥作用。现在我们开始在我们的开发环境中得到这个。我想在它开始在生产中发生之前修复它,因为那会很糟糕。当您说负域时,您的意思是使用负数作为主键吗?那么某人的 ID 可能是 -100?
    • 由 IDENTITY 列填充的 ID 列是用作主索引的代理键。负域将确保人类提供的值不会干扰您分配给 Teradata 以用于生成 IDENTITY 值的域。主键是强制员工唯一性的逻辑结构。 Teradata 中的主索引(无论是否唯一)是一种物理构造,可确定整个 AMPS 的数据分布。
    • 您能否创建此表的副本,并将 IDENTITY 列定义为 GENERATED ALWAYS ... NO CYCLE 并尝试在开发中重现该问题?
    猜你喜欢
    • 1970-01-01
    • 2015-05-14
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 2013-06-29
    • 1970-01-01
    • 2016-07-14
    相关资源
    最近更新 更多