2016-01-21 177 views
1

問題: SQL Server允許將尾隨空格添加到外鍵!外鍵允許的尾隨空格

這種行爲當然會導致應用程序中出現各種不需要的行爲。這怎麼能停下來?

實施例:兩個表中1:n的關係:

create table products 
(
    pid nvarchar(20) primary key 
;) 

create table sales 
(
    pid nvarchar(20) references products(pid), 
    units int 
); 

現在插入主鍵'A'

insert into products (pid) values ('A'); 

現在,插入外鍵:

-- 'A' is accepted, as expected: 
insert into sales (pid, units) values ('A', 23); 

-- 'B' is declined, as expected: 
insert into sales (pid, units) values ('B', 12); 

-- 'A ' (with a trailing space) 
-- This is ACCEPTED, but of course this is NOT EXPECTED !! 
insert into sales (pid, units) values ('A ', 12); 
+0

檢查您的'ANSI_PADDING'設置。 https://msdn.microsoft.com/en-us/library/ms187403.aspx –

+1

另請參見http://dba.stackexchange.com/q/56876 –

+0

@ShannonSeverance我不希望刪除尾部空格。我只希望'A'和'A'受到不同的待遇! –

回答

1

如果你只是不想讓尾隨空格:

create table sales 
(
    pid nvarchar(20) references products(pid), 
    units int, 
    constraint CK_sales_pid CHECK (RIGHT(pid,1) <> ' ') 
); 

否則,你需要認識到,這不僅僅是一個「意外」情況。 SQL標準說,當有兩個長度不等的字符串時,較短的字符串首先用空格填充以使長度相等,然後再進行比較。

+0

是的,謝謝。理論上,我希望表達式'('A'='A')'返回錯誤而不正確。但它似乎深深植根於SQL Server,無法更改。 (或?)因此,像你這樣的檢查約束是一個實用的解決方案。順便說一句,Oracle的行爲有所不同,而且自從我與Oracle合作多年以來,我感到「非常震驚」。 –

+2

對於外鍵,Oracle的行爲是不同的,但是對於比較而言是相同的。 '從'dual'選擇'true','x'='x';'返回一行,'返回true'。 –

2

的第二個問題是,這是真的很難檢測,因爲:

select pid from sales group by pid 

只返回一個值:一個在你的榜樣

這裏有個竅門,以幫助檢測問題:

select pid from sales group by binary(pid) 

這將返回2行:A和A(具有尾隨空格)

乾杯,

+0

是的,謝謝你!這個問題也是在這種情況下,表達式'A'='A''是真的!因此,當然,這兩個要素組合在一起。同時我從中學到了,所有的表都有檢查約束。沒有尾隨空格。對於鑰匙,領先的空間也是不允許的。 –