Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server:主键冲突_Sql_Sql Server_Key - Fatal编程技术网

SQL Server:主键冲突

SQL Server:主键冲突,sql,sql-server,key,Sql,Sql Server,Key,首先,我想为您即将体验到的混乱代码道歉,但这对我的观点很重要。我已经简化了一些,但下面是我正在使用的代码: create table [TableExample]( ID varchar(50) primary key not null, ); with CTE as ( select case when ltrim(rtrim(S1.ID)) is null then convert(varchar(50),newid()) e

首先,我想为您即将体验到的混乱代码道歉,但这对我的观点很重要。我已经简化了一些,但下面是我正在使用的代码:

create table [TableExample](
    ID varchar(50) primary key not null,
);

with CTE as (
    select case when ltrim(rtrim(S1.ID)) is null
            then convert(varchar(50),newid())
            else ltrim(rtrim(S1.ID))
        end as 'ID',
    row_number()over(partition by ltrim(rtrim(S1.ID)) order by newid()) as 'duplicates' 
    from [DB2].[dbo].[Source1] as S1
    full outer join [DB2].[dbo].[Source2] as S2
        on S2.[ID]=S1.[ID]
    full outer join [DB2].[dbo].[Source3] as S3
        on S3.[ID]=S1.[ID])

insert into [dbo].[TableExample] (
    [ID]
)

select  distinct case 
        when [duplicates] > 1
            then convert(varchar(50),newid())
            else CTE.[ID]
        end as 'ID'
from [DB2].[dbo].[Source1] as S1
full outer join [DB2].[dbo].[Source2] as S2
    on ltrim(rtrim(S2.ID))=ltrim(rtrim(S1.ID))
full outer join [DB2].[dbo].[Source3] as S3
    on ltrim(rtrim(S3.ID))=ltrim(rtrim(S1.ID))
full outer join CTE on CTE.ID=ltrim(rtrim(S1.ID))
where (S2.ID is not null or S3.ID is not null or S1.ID is not null)
    and [duplicates] = 1
如您所见,我正在运行多个非常冗余的检查,以确保主键字段[ID]不会收到任何重复项。我选择distinct,使用CTE标记任何重复的密钥,然后拒绝它们,最后,如果有任何密钥仍然通过,我将重复的密钥更改为

convert(varchar(50),newid())
然而,每次我运行它时,我都会遇到一个重复的键错误

如果你想知道,是的,我每次都会放下桌子,只是为了确保没有保留任何可能导致错误的东西


有超过100000行的数据需要输入,我对这件事束手无策。任何建议都将不胜感激

似乎您正在尝试合并来自Source1、Source2和Source3的ID,修剪它们,并查找重复的ID。如果有重复的行,保留其中一行,并用新的唯一标识符替换其他行。这正好实现了:

CREATE TABLE TableExample ( ID VARCHAR(50) PRIMARY KEY NOT NULL)
CREATE TABLE Source1 ( ID VARCHAR(50) PRIMARY KEY NOT NULL)
CREATE TABLE Source2 ( ID VARCHAR(50) PRIMARY KEY NOT NULL)
CREATE TABLE Source3 ( ID VARCHAR(50) PRIMARY KEY NOT NULL)

INSERT INTO Source1 VALUES ('6C0240E7-847B-41F3-9DCA-D2EA54FB0E96'), (' 6C0240E7-847B-41F3-9DCA-D2EA54FB0E96 '), ('007171B1-10DB-4DD2-832F-026C968AC19A'), ('A28976BC-443F-44E6-9AED-B41DAFBBB651')
INSERT INTO Source2 VALUES ('6C0240E7-847B-41F3-9DCA-D2EA54FB0E96 '), ('007171B1-10DB-4DD2-832F-026C968AC19A'), ('80373FA7-5A61-41AB-B7DA-1F807A0E442B'), ('A38C6C43-A2B1-4C5B-8699-601054FB7968')
INSERT INTO Source3 VALUES ('  6C0240E7-847B-41F3-9DCA-D2EA54FB0E96 '), ('1A366E5C-0B6C-4B3D-B3E4-126035D641F1'), ('1183D160-AF00-43C1-8EA1-E953B51918E4'), (' 80373FA7-5A61-41AB-B7DA-1F807A0E442B ')

;WITH CTE AS
(
    SELECT RTRIM(LTRIM(ID)) ID
    FROM Source1 
    UNION ALL
    SELECT RTRIM(LTRIM(ID)) ID
    FROM Source2
    UNION ALL
    SELECT RTRIM(LTRIM(ID)) ID
    FROM Source3
),
CTE2 AS
(
    SELECT ID, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY NEWID()) AS RN
    FROM CTE
)
INSERT INTO TableExample (ID)
SELECT CASE WHEN RN > 1 THEN CAST(NEWID() AS VARCHAR(50)) ELSE ID END AS ID
FROM CTE2

SELECT * FROM TableExample
产出:

ID
007171B1-10DB-4DD2-832F-026C968AC19A
0841CEF6-B70E-442F-90CD-B79C235107F9
0AE6C8EC-31CF-49EA-B992-09E0CDC32B61
1183D160-AF00-43C1-8EA1-E953B51918E4
16EE8FD4-E5C9-480E-98DB-1410DCB0CFF5
1A366E5C-0B6C-4B3D-B3E4-126035D641F1
2C5F8AE0-CE70-406C-96C4-FE5144C16634
6C0240E7-847B-41F3-9DCA-D2EA54FB0E96
80373FA7-5A61-41AB-B7DA-1F807A0E442B
A28976BC-443F-44E6-9AED-B41DAFBBB651
A38C6C43-A2B1-4C5B-8699-601054FB7968
CB426799-E85E-4D13-AC6A-16ACC571333A

能否提供表Source1、Source2和Source3的示例数据,并解释您要查找的重复项?令人困惑的是,在CTE中,Source2和Source3是连接在一起的,但它们没有被使用。副本是否分散在这些表格中?您可能需要联合而不是联接。错误消息标识了重复的值。因此,删除insert语句,只需对上面提到的ID值运行select查询。而你的逻辑是密集的,正如所写的,毫无意义。您是否假设ID在每个表中都是唯一的?CTE和实际select语句中的完全连接的重复很难理解——不一致的连接逻辑使情况变得更糟。很少有人需要修剪连接线,但是如果你这样做了,为什么不在cte中修剪呢?我正在尝试这个建议的一个变体。我提供的代码显然有点过于简化。除了ID之外,还有其他字段,并且它们与每个源不同,因此它确实需要是一个连接,而不是联合。尽管如此,即使有了改变,它看起来也比我以前拥有的干净多了。我将再次发布结果。是的!修改后的代码运行得非常好,谢谢。我对你的评论投了更高的票,但由于时间关系,没有公开发表