如何在某些行上可能具有NULL值的列上创建唯一索引?

2020-09-02 01:58发布

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


我有下表。 对于具有" IdLoc"和" IdSeq"的记录,我需要在" IdLoc"和" IdSeq"上具有唯一索引。 换句话说,某些事务将具有" IdLoc"和" IdSeq"(这是对另一个表的引用),而其他事务则没有。 但是,我需要确保只有一个事务指向给定的" IdLoc"和" IdSeq"。

我添加了唯一索引,但是我很确定它不会起作用,因为对于某些记录," IdLoc"和" IdSeq"将为NULL。

有什么建议吗?

爱德加德

创建表dba.m_Trans(
 IdTrans VARCHAR(10)NOT NULL,
 TransDate DATE NOT NULL,
 IdWorkCenter VARCHAR(10)NOT NULL,
 IdFactory VARCHAR(10),
 NumTrans INTEGER NOT NULL,
 TransType INTEGER,
 状态UNSIGNED TINYINT NOT NULL DEFAULT 0,
 IdLoc UNSIGNED TINYINT,
 IdSeq整数,
 ...其他一些东西
 主键(IdTrans)
 );
 -唯一索引
 在m_Trans上创建唯一索引m_Tran_ITRANS(IdLoc ASC,IdSeq ASC); 

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


我有下表。 对于具有" IdLoc"和" IdSeq"的记录,我需要在" IdLoc"和" IdSeq"上具有唯一索引。 换句话说,某些事务将具有" IdLoc"和" IdSeq"(这是对另一个表的引用),而其他事务则没有。 但是,我需要确保只有一个事务指向给定的" IdLoc"和" IdSeq"。

我添加了唯一索引,但是我很确定它不会起作用,因为对于某些记录," IdLoc"和" IdSeq"将为NULL。

有什么建议吗?

爱德加德

创建表dba.m_Trans(
 IdTrans VARCHAR(10)NOT NULL,
 TransDate DATE NOT NULL,
 IdWorkCenter VARCHAR(10)NOT NULL,
 IdFactory VARCHAR(10),
 NumTrans INTEGER NOT NULL,
 TransType INTEGER,
 状态UNSIGNED TINYINT NOT NULL DEFAULT 0,
 IdLoc UNSIGNED TINYINT,
 IdSeq整数,
 ...其他一些东西
 主键(IdTrans)
 );
 -唯一索引
 在m_Trans上创建唯一索引m_Tran_ITRANS(IdLoc ASC,IdSeq ASC); 
付费偷看设置
发送
4条回答
何必丶何苦呢
1楼-- · 2020-09-02 02:39

我想在克里斯的回答中加点内容。

这取决于您的意思是" [我很确定]它不起作用"。

如果您想确保INSERT或UPDATE语句不会失败,则索引声明比Chris的建议适用于更多情况,因为默认行为是"带有null分开",并且意味着多个(成对的)NULL 允许使用值,因为它们不相同。 在这里,我们搞砸了三个值的逻辑。 根据ANSI标准,两个NULL值既不相同也不不同。 强调第一部分(如默认行为或"具有null的不同"子句),多个NULL值不违反唯一性。 他们强调第二部分。

经济低迷:有一个假设 选择可能会或可能不会与您的方法一起使用,但将可靠地与Chris的方法一起使用:在查询具有类似模式的表时

从m_Trans中选择*,其中IdLoc = @IdLoc和IdSeq = @IdSeq

如果这些列的组合被唯一索引覆盖,则您最多可能期望有一个结果行。 只要将ANSINULL选项设置为" On"(默认设置),情况就一直如此。 如果将其设置为" Off",并且至少一个变量为NULL,则使用索引声明查询可能会返回多行。

我希望这可以消除更多的混乱...

关于Volker
DB-Tec 知识

Climb_Ma
2楼-- · 2020-09-02 02:56

复制代码段:

-删除表t_uniq_null;
创建表t_uniq_null
(rid unsigned int not null primary key default autoincrement,
c1 smallint null,
c2 smallint null,
c3 smallint null) ;

在t_uniq_null(c1)上创建唯一索引i1;
在t_uniq_null(c2)上创建唯一索引i2,其中null分开;
在t_uniq_null(c3)上创建唯一索引i3,其中null不唯一;

-从t_uniq_null中选择*;

插入t_uniq_null(c1,c2,c3)值(1、2、3);
插入t_uniq_null(c1,c2)值 (4,5);
插入t_uniq_null(c2,c3)值(4,5);
插入t_uniq_null(c1,c3)值(6,7);
插入t_uniq_null(c1,c3) ,c2)值(8,9); -i3违反了
插入t_uniq_null(c2,c3)值(8,9);
插入t_uniq_null(c1,c3)值(2,1);
从t_uniq_null中选择*;

骆驼绵羊
3楼-- · 2020-09-02 02:42
创建唯一索引m_Tran_ITRANS

      在m_Trans(IdLoc ASC,IdSeq ASC)上

 空值不是唯一的; 
bbpeas
4楼-- · 2020-09-02 03:05

感谢两者。

您是对的Volker,索引有效。 我遇到了包含NOT NULL值和NULL值的唯一键的问题。 所以我认为这行不通。

再次感谢!

一周热门 更多>