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
Odpowiedz
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 VIRTUAL
DECODE
obsługuje wymóg dla Ciebie.
podejście 10g
Można spełnienia wymogu korzystania -
DEFAULT
wartość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".
dlaczego warto użyć wyzwalacza PO, w przeciwieństwie do wyzwalacza PRZED? –
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". –
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.
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 ...
Masz na myśli zły projekt? Nie ma mocy ... – user2672165
Tak źle zaprojektowana. Edytowałem tekst: – Charmi
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. –
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.
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
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. –
Pamiętaj, że' DECODE' jest poprawne tylko w SQL nie PL/SQL. CASE jest ważny w obu przypadkach. – Unoembre
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. –
może dodać do tego spust podczas wstawiania? –
'WIRTUALNA kolumna' z funkcją' DECODE' jest wszystkim, czego potrzebujesz. –