2017-04-20 98 views
2

我有一個允許的值列表,例如:貓,鼠標,狗和鸚鵡。 現在我想有可能在這個列表中以分號(;)隔開的單元格中添加許多值。用逗號分隔的字符串匹配特定的單詞

這意味着我可以添加:

貓;狗;鼠標

貓;鸚鵡

鼠標;貓

鸚鵡

但我不能添加

獅子;貓

鼠標;鸚鵡;獅子

貓;(這意味着不能在末尾添加一個分號)

貓;鼠標;

;(這意味着我不能只是添加一個分號) 我嘗試寫使用此功能REGEXP_LIKE的約束,但這並不正常工作。

not REGEXP_LIKE (animal, '[^(the cat| the mouse |the dog|the parrot|;)]', 'i') 

NB:動物是我申請的限制

+2

不這樣做。不要在一個列中存儲由某些字符分隔的多個值。閱讀數據庫規範化。不要走這條路。 –

回答

1

前置分隔符的字符串匹配,那麼像這樣的列:

REGEXP_LIKE(
    ';' || animal, 
    '^(;\s*(the cat|the mouse|the dog|the parrot)\s*)*$', 
    'i' 
) 

更新

你可以使用第二個表(帶外鍵引用)或嵌套表:

CREATE TYPE stringlist IS TABLE OF VARCHAR2(4000); 
/

CREATE TABLE animals (
    id   number, 
    animal_list stringlist 
) NESTED TABLE animal_list STORE AS animals__animal; 

ALTER TABLE ANIMALS__ANIMAL ADD CONSTRAINT animals__animal__chk 
    CHECK (TRIM(BOTH FROM LOWER(column_value)) 
      IN ('the cat', 'the mouse', 'the dog', 'the parrot')); 

INSERT INTO animals VALUES (1, StringList('the cat', ' the dog ')); 
-- Succeeds 
INSERT INTO animals VALUES (2, StringList('the cat', 'the horse')); 
-- Fails with ORA-02290: check constraint (TEST.ANIMALS__ANIMAL__CHK) violated 

然後,你可以這樣做:

SELECT id, 
     (SELECT LISTAGG(COLUMN_VALUE, ';') WITHIN GROUP (ORDER BY ROWNUM) 
     FROM TABLE(a.animal_list)) AS animals 
FROM animals a; 

,輸出:

ID ANIMALS 
-- ----------------- 
1 the cat; the dog 
+0

感謝您的回答,這是有幫助的。但我已經省略了,表示我想要插入值爲null或無值的可能性。我嘗試修改你的答案,就像這樣regexp_like(';'|| categories,'^(; \ s *(the cat | the mouse | the dog | the parrot | null | |)s)* $','一世')。但我現在可以插入null; – van

+0

@VannessaKemeni在Oracle中'NULL'和一個空字符串是相同的東西,所以你可以這樣做:'CHECK(animal IS NULL OR REGEXP_LIKE(...))' – MT0

+0

真的不是:我添加約束動物是空的,但是當我想頂部插入值'空',這是行不通的。所以我已經在regexp_like(...)中添加了這個值。 – van

0

對於正則表達式的一部分,我相信這是最簡單的正則表達式驗證不需要操縱數據(注在';'之後有空格)

^(the cat|the mouse|the dog|the parrot|;)+$