SQL/C# - Primary Key error on UPSERT

你。 提交于 2020-01-14 13:46:29

问题


UPDATE(simplified problem, removed C# from the issue)

How can I write an UPSERT that can recognize when two rows are the same in the following case...

See how there's a \b [backspace] encoded there (the weird little character)? SQL sees these as the same. While my UPSERT sees this as new data and attempts an INSERT where there should be an UPDATE.


//UPSERT
    INSERT INTO [table]
    SELECT [col1] = @col1, [col2] = @col2, [col3] = @col3, [col4] = @col4
    FROM [table]
    WHERE NOT EXISTS
       -- race condition risk here?
       ( SELECT 1 FROM [table] 
       WHERE 
            [col1] = @col1 
        AND [col2] = @col2
        AND [col3] = @col3)

    UPDATE [table]
        SET [col4] = @col4
        WHERE 
        [col1] = @col1 
        AND [col2] = @col2
        AND [col3] = @col3

回答1:


You need the @ sign, otherwise a C# character escape sequence is hit.

C# defines the following character escape sequences:

\' - single quote, needed for character literals 
\" - double quote, needed for string literals 
\\ - backslash 
\0 - Unicode character 0 
\a - Alert (character 7) 
\b - Backspace (character 8) 
\f - Form feed (character 12) 
\n - New line (character 10) 
\r - Carriage return (character 13) 
\t - Horizontal tab (character 9) 
\v - Vertical quote (character 11) 
\uxxxx - Unicode escape sequence for character with hex value xxxx 
\xn[n][n][n] - Unicode escape sequence for character with hex value nnnn (variable length version of \uxxxx) 
\Uxxxxxxxx - Unicode escape sequence for character with hex value xxxxxxxx (for generating surrogates) 



回答2:


After hours of tinkering it turns out I've been on a wild goose chase. The problem is very simple. I pulled my UPSERT from a popular SO post. The code is no good. The select will sometimes return > 1 rows on INSERT. Thereby attempting to insert a row, then insert the same row again.

The fix is to remove FROM

    //UPSERT
    INSERT INTO [table]
    SELECT [col1] = @col1, [col2] = @col2, [col3] = @col3, [col4] = @col4
    --FROM [table] (Dont use FROM..not a race condition, just a bad SELECT)
    WHERE NOT EXISTS
       ( SELECT 1 FROM [table] 
       WHERE 
            [col1] = @col1 
        AND [col2] = @col2
        AND [col3] = @col3)

    UPDATE [table]
        SET [col4] = @col4
        WHERE 
        [col1] = @col1 
        AND [col2] = @col2
        AND [col3] = @col3

Problem is gone.

Thanks to all of you.




回答3:


You are using '\u' which generates a Unicode character.

Your column is a varchar, which does not support Unicode characters. nvarchar would support the character.



来源:https://stackoverflow.com/questions/7263445/sql-c-primary-key-error-on-upsert

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!