涉及字符串字段的唯一键

Posted

技术标签:

【中文标题】涉及字符串字段的唯一键【英文标题】:Unique Key involving string fields 【发布时间】:2015-02-09 19:59:01 【问题描述】:

我在实现唯一键约束时遇到了一些问题。

它有 3 个字段,其中一个是字符串。问题是我在发送这两行时违反了唯一键:

数据库

First: Id-type int
Second: PosId-type uniqueidentifier
Third: Description-type nvarchar(256)

定义的约束

ALTER TABLE dbo.StAPSachverhalte ADD CONSTRAINT
    UQ_myuniqueKey UNIQUE NONCLUSTERED 
    (
        CompanyId,
        PosId,
        Description
    ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

C#参数代码

new SqlParameter("@Description", SqlDbType.NVarChar, 256),
new SqlParameter("@PosId", SqlDbType.UniqueIdentifier),
...
MyParameters1[0].Value = _newData.Description;
MyParameters1[1].Value = _newData.PosId;

CommandText

@"INSERT INTO StAPSachverhalte( 
                    [Description], 
                    [PosId] 
                    ) 
                VALUES ( 
                    @Description, 
                    @PosId) 
                SET @ID = SCOPE_IDENTITY()",

已发送条目

'1, random GUID, 001'

'1, random GUID, 001 '

如果我没记错的话,两者都应该是有效的,因为 '001' '001'。

错误

Cannot insert duplicate key in object 'dbo.XXX'. The duplicate key value is (76, 9bcba4e1-4d16-487c-977f-cda933bb0955, 0001 ).

我尝试通过使用参数的普通 sqlcommand executenonquery 保存数据,并检查 myparameter[index] 是否包含相应的值,末尾有一个空格。

有什么想法吗?

【问题讨论】:

您的唯一约束中有哪些字段? 这三个字段应该是唯一的。我省略了其余的,因为他们快 15 岁了...... 你的数据库是什么,你如何声明数据库中的列(类型、长度等),你用来执行 SQL 命令的代码,所有需要帮助的信息 在任何情况下,我都会说 SQL 命令在字符串周围不带引号发送,因此您发送的是两个相同的行。 实际上 '001' 和 '001' 对于 SQL 来说是相等的 :) 在 SSMS 查询窗口中尝试“select case when '001' = '001' then 1 else 0 end”... 【参考方案1】:

经过一番研究,我发现答案是,虽然您确实发送了两个不同的字符串,但 DB 比较字符串时没有考虑尾随空格。包括插入时的唯一比较。

因此,要按您的意愿工作,您必须添加另一个字段,例如字符串的长度,如下所示:mysql database with unique fields ignored ending spaces

【讨论】:

此解决方案是否也适用于事务 sql? @blacai,就我能找到的,是的。

以上是关于涉及字符串字段的唯一键的主要内容,如果未能解决你的问题,请参考以下文章

MySQL - InnoDB主键索引、普通索引、唯一索引、联合索引

Access 中的级联字段加入

22 高级SQL特性

oracle生成主键唯一的id,函数SYS_GUID()

一个字符串表:添加一个 int 键,还是不添加?

navicat for mysql 如何设置多个字段唯一?