2014-12-30 15 views
5

Witam programistę z prośbą o dodanie kolumny do tabeli, która będzie miała domyślną wartość "N", jednak jeśli pozycja ma identyfikator = 3, wówczas domyślna wartość tej kolumny powinno być "Y", czy mogę to osiągnąć w wyroczni?Orace: domyślna wartość kolumny oparta na filtrze

+0

Generalnie obsługuję takie rzeczy od strony aplikacji. po prostu 'column = 'N'; if (id == 3), a następnie kolumna = "Y"; ----- przechowywać wiersz w DB ------ '. i jeśli istnieją już wiersze w DB, po prostu zaktualizuj kolumnę za pomocą instrukcji 'case when' dla istniejących wierszy. –

+1

może dodać do tego spust podczas wstawiania? –

+1

'WIRTUALNA kolumna' z funkcją' DECODE' jest wszystkim, czego potrzebujesz. –

Odpowiedz

0

podejście 11g

Od Oracle 11g iw górę, można zrobić to w jednym kroku stosując VIRTUAL columns.

przypadek testowy

SQL> CREATE TABLE tab_default (
    2 ID   NUMBER, 
    3 flag varchar2(1) GENERATED ALWAYS AS (decode(id, 3, 'Y', 'N')) VIRTUAL 
    4 ); 

Table created. 

SQL> 
SQL> INSERT INTO tab_default (ID) VALUES (1); 

1 row created. 

SQL> INSERT INTO tab_default (ID) VALUES (3); 

1 row created. 

SQL> INSERT INTO tab_default (ID) VALUES (10); 

1 row created. 

SQL> SELECT * FROM tab_default; 

     ID F 
---------- - 
     1 N 
     3 Y 
     10 N 

SQL> 

Więc funkcja w deklaracji kolumny VIRTUALDECODE obsługuje wymóg dla Ciebie.

podejście 10g

Można spełnienia wymogu korzystania -

  1. DEFAULT wartość
  2. AFTER INSERT TRIGGER gdy id = 3

Utwórz tabelę mieć DEFAULT wartość jako ' N '. Niech wyzwalacz wystrzeli tylko wtedy, gdy wstawiony zostanie nowy wiersz o wartości w kolumnie id = 3, tak aby wyzwalacz zaktualizował wartość do "Y". W pozostałych przypadkach domyślną wartością byłoby "N".

+0

dlaczego warto użyć wyzwalacza PO, w przeciwieństwie do wyzwalacza PRZED? –

+0

Ponieważ po wyzwoleniu co najmniej zapewnia, że ​​transakcja została przeniesiona do przodu. Jeśli jesteś zależny od wcześniejszego wyzwalacza i wprowadzasz na nim zmiany, MOGĄ NIE być poręczycielem. Nie zrobi to jednak wielkiej różnicy, w takich przypadkach wolę spust po. Nawiasem mówiąc, nie jestem wielkim fanem wyzwalaczy, ponieważ są one efektem działania, a więc efektem ubocznym. Ale w tym przypadku, jeśli ktoś nie jest na "11g", to jest to jedyny sposób. I to był główny powód, dla którego zredagowałem swoją odpowiedź i przeniosłem podejście "11g" powyżej podejścia "10g'trigger". –

0

Po dodaniu nowej kolumny do tabeli można wstawić wartość w kolumnie za pomocą poniższego zapytania:

update table_name set column_name = (case when id = 3 then 'Y' else 'N' end);  

Na wstawiania nowych rekordów można użyć poniżej podejścia:
1) decyduje kolumnę w czasie tworzenie kwerendy wstawiania, możesz dodać do tego logikę podczas tworzenia kwerendy.
2) Utwórz wyzwalacz w bazie danych, który powinien zaktualizować wartość kolumny po wstawieniu dowolnego nowego wiersza do tabeli.

0

To jest bardzo kiepski projekt bazy danych. Nie respektuje normalnej formy relacyjnej bazy danych. Sugeruję zachowanie tabeli w obecnej formie i utworzenie nowego widoku tabeli z dodatkową kolumną obliczaną przy użyciu DECODE lub CASE WHEN ...

+0

Masz na myśli zły projekt? Nie ma mocy ... – user2672165

+0

Tak źle zaprojektowana. Edytowałem tekst: – Charmi

+0

Nie każda aplikacja mogła zostać naprawiona z dnia na dzień. I dlatego potrzebujemy obejść tymczasowo, dopóki nie zostanie znalezione i wdrożone rozwiązanie trwałe. –

0

Zgadzam się z komentatorami, którzy wspomnieli, że nie jest to dobre projekt bazy danych. Mimo to kompromisy z projektowaniem baz danych nie są niczym niezwykłym w rzeczywistych sytuacjach.

Nie jestem pewien, czy jest to wirtualna kolumna. OP poprosił o sposób na ustawienie domyślne; wirtualna kolumna działa inaczej niż domyślne ograniczenie (np. z domyślnym ograniczeniem możemy wstawić inną wartość niż domyślna do kolumny.Najlepszą trasą do podjęcia może być użycie wyzwalacza do ustawienia "domyślnej" wartości:

CREATE OR REPLACE TRIGGER mytrigger 
    BEFORE INSERT ON mytable FOR EACH ROW 
    WHEN (new.mycolumn IS NULL) 
BEGIN 
    SELECT DECODE(id, 3, 'Y', 'N') INTO :new.mycolumn FROM dual; 
END; 
/

wyzwalacz będzie również pracować czy używasz Oracle 10g lub 11g (z których oba otagowaniu).

nadzieję, że to pomaga.

+0

Jeśli użyjesz ': new.mycolumn: = CASE: new.id KIEDY 3 THEN 'Y' ELSE 'N' END;' zamiast 'SELECT', zapisujesz koszt skoku dla silnika PL/SQL do SQL silnik i tył tylko w celu wykonania testu IF. Nie wierzę też, że twoje odniesienie do "id" będzie w zakresie bez ': new. 'Z przodu. Z zadowoleniem przyjmuję także komentarz dotyczący używania słowa ": old" zamiast ": new" tutaj. – Unoembre

+0

Dzięki za komentarz, myślę, że masz rację co do wszystkiego, o czym wspomniałeś. Można też użyć 'DECODE (: new.id, 3,'Y ',' N ')' zamiast 'CASE' itd. –

+0

Pamiętaj, że' DECODE' jest poprawne tylko w SQL nie PL/SQL. CASE jest ważny w obu przypadkach. – Unoembre

Powiązane problemy