Advertisement
Guest User

Untitled

a guest
Jan 15th, 2017
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.22 KB | None | 0 0
  1. SQL
  2.  
  3. SELECT * FROM SYS.USER_ERRORS;
  4.  
  5.  
  6. /* Tworzenie tabel testowych */
  7.  
  8. DROP TABLE Client;
  9.  
  10. CREATE TABLE Client
  11. (
  12. client_id NUMBER(4) NOT NULL PRIMARY KEY,
  13. name VARCHAR(30),
  14. email VARCHAR(30)
  15. );
  16.  
  17. DROP TABLE Order_;
  18.  
  19. CREATE TABLE Order_
  20. (
  21. order_id NUMBER(4) NOT NULL PRIMARY KEY,
  22. client_id NUMBER(4) NOT NULL,
  23. order_date DATE,
  24. shipment_date DATE
  25. );
  26.  
  27. DROP TABLE Product;
  28.  
  29. CREATE TABLE Product
  30. (
  31. product_id NUMBER(4) NOT NULL PRIMARY KEY,
  32. order_id NUMBER(4) NOT NULL,
  33. product_name VARCHAR(30),
  34. price NUMBER(5,2)
  35. );
  36.  
  37.  
  38.  
  39. ======= 1 ==========
  40.  
  41. CREATE SEQUENCE product_primary_key_generator
  42. START WITH 1
  43. INCREMENT BY 1
  44. NOCACHE
  45. NOCYCLE;
  46.  
  47.  
  48. /* Sprawdzenie */
  49. SET SERVEROUTPUT ON
  50. DECLARE
  51. val number(4);
  52. BEGIN
  53. SELECT product_primary_key_generator.nextval
  54. INTO val
  55. FROM dual;
  56. dbms_output.put_line(val);
  57. END;
  58. /
  59.  
  60. /* Wynik: */
  61. 1
  62.  
  63.  
  64.  
  65. ======= 2 ==========
  66.  
  67. /* Tworzenie funkcji wstawiającej dane do tabeli Product */
  68.  
  69. CREATE OR REPLACE FUNCTION insertProduct(name IN varchar, price IN number, orderId IN number)
  70. RETURN number IS
  71. newIndex number(4) := 0;
  72. BEGIN
  73. SELECT product_primary_key_generator.nextval
  74. INTO newIndex
  75. FROM dual;
  76.  
  77. INSERT INTO Product (product_id, order_id, product_name, price) VALUES (newIndex, orderId, name, price);
  78. RETURN newIndex;
  79. END;
  80. /
  81.  
  82.  
  83.  
  84.  
  85.  
  86. /* Sprawdzenie */
  87. DECLARE
  88. newIndex number;
  89. BEGIN
  90. newIndex:= insertProduct('nowy produkt', 50, 2);
  91. dbms_output.put_line('Dodano wiersz do tabeli Upust o id ' || newIndex);
  92. END;
  93. /
  94.  
  95. SELECT * FROM Product;
  96.  
  97.  
  98. === WYNIK ===
  99.  
  100. Dodano wiersz do tabeli Upust o id 2
  101.  
  102. PRODUCT_ID ORDER_ID PRODUCT_NAME PRICE
  103. ---------- ---------- ------------------------------ ----------
  104. 2 2 nowy produkt 50
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112. ======= 3 =======
  113.  
  114. CREATE OR REPLACE VIEW Client_products AS
  115. SELECT c.name, c.email, o.order_date, o.shipment_date, p.product_name, p.price
  116. FROM Client c, Order_ o, Product p
  117. WHERE c.client_id = o.client_id
  118. AND o.order_id = p.order_id;
  119.  
  120.  
  121.  
  122. 4]
  123. /* Tworzenie sekwencji do pobierania kolejnych id tabeli Order */
  124.  
  125. CREATE SEQUENCE order_primary_key_generator
  126. START WITH 1
  127. INCREMENT BY 1
  128. NOCACHE
  129. NOCYCLE;
  130.  
  131. /* Tworzenie danych testowych */
  132.  
  133. INSERT INTO Client (client_id, name, email) VALUES (1, 'Client1', 'client@gmail.com');
  134.  
  135. /* Wyzwalacz */
  136.  
  137. CREATE OR REPLACE TRIGGER Client_products_insert
  138. INSTEAD OF INSERT ON Client_products
  139. FOR EACH ROW
  140. DECLARE
  141. clientId Client.client_id%TYPE;
  142. newOrderindex number(4);
  143. newProductindex number(4);
  144.  
  145. BEGIN
  146. SELECT client_id INTO clientId
  147. FROM Client c
  148. WHERE c.name = :NEW.name
  149. AND c.email = :NEW.email;
  150.  
  151.  
  152. BEGIN
  153. SELECT order_id INTO newOrderindex
  154. FROM Order_ o
  155. WHERE o.client_id = clientId
  156. AND o.order_date = :NEW.order_date
  157. AND o.shipment_date = :NEW.shipment_date;
  158.  
  159. RAISE DUP_VAL_ON_INDEX;
  160.  
  161. EXCEPTION
  162. WHEN NO_DATA_FOUND THEN
  163. SELECT order_primary_key_generator.nextval
  164. INTO newOrderindex
  165. FROM dual;
  166.  
  167. INSERT INTO Order_ (order_id, client_id, order_date, shipment_date)
  168. VALUES (newOrderindex, clientId, :NEW.order_date, :NEW.shipment_date);
  169.  
  170. SELECT product_primary_key_generator.nextval
  171. INTO newProductindex
  172. FROM dual;
  173.  
  174. INSERT INTO Product (product_id, order_id, product_name, price)
  175. VALUES (newProductindex, newOrderindex, :NEW.product_name, :NEW.price);
  176.  
  177. WHEN DUP_VAL_ON_INDEX THEN
  178. dbms_output.put_line('Zamowienie zostalo juz zdefiniowane wczesniej');
  179.  
  180. END;
  181.  
  182.  
  183. EXCEPTION
  184. WHEN NO_DATA_FOUND THEN
  185. dbms_output.put_line('Uzytkownik o podanych danych nie istnieje');
  186. END;
  187. /
  188.  
  189.  
  190.  
  191. INSERT INTO Client_products (name, email, order_date, shipment_date, product_name, price)
  192. VALUES ('zle imie', 'client@gmail.com', SYSDATE, SYSDATE, 'nowy produkt', 100);
  193.  
  194. > Uzytkownik o podanych danych nie istnieje
  195.  
  196. INSERT INTO Client_products (name, email, order_date, shipment_date, product_name, price)
  197. VALUES ('Client1', 'client@gmail.com', '17/01/15', '17/01/15', 'kolejny produkt', 100);
  198.  
  199. > 1 wiersz został utworzony.
  200.  
  201.  
  202. SELECT * FROM Order_;
  203.  
  204. >
  205. ORDER_ID CLIENT_ID ORDER_DA SHIPMENT
  206. ---------- ---------- -------- --------
  207. 1 1 17/01/15 17/01/15
  208.  
  209.  
  210. SELECT * FROM Product;
  211.  
  212. >
  213. PRODUCT_ID ORDER_ID PRODUCT_NAME PRICE
  214. ---------- ---------- ------------------------------ ----------
  215. 2 2 nowy produkt 50
  216. 3 1 kolejny produkt 100
  217.  
  218.  
  219. INSERT INTO Client_products (name, email, order_date, shipment_date, product_name, price)
  220. VALUES ('Client1', 'client@gmail.com', '17/01/15', '17/01/15', 'kolejny produkt', 100);
  221.  
  222. > Zamowienie zostalo juz zdefiniowane wczesniej
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229. ============ 5 ===========
  230. FOR UPDATE
  231. ----------
  232. Dodanie klauzuli FOR UPDATE sprawi że wiersze te zostaną zablokowane dla innych użytkowników do czasu, aż nie zatwierdzimy transakcji (COMMIT), lub jej
  233.  
  234. nie wycofamy (ROLLBACK).
  235. Po klauzuli „for update” można wymienić tylko te kolumny które będziemy updatować. W przypadku blokady na jednej tabeli i tak zostaną zablokowane całe
  236.  
  237. wiersze. Jeśli po FOR UPDATE wymienimy kolumny, ale zapytanie oparte jest o więcej niż jedną tabelę, zablokowane zostaną wiersze tylko w tej tabeli
  238.  
  239. której kolumny wymienimy po FOR UPDATE.
  240.  
  241.  
  242. Zastosowanie klauzuli NOWAIT:
  243. -----------------------------
  244. Gdy w czasie trwania blokady inny użytkownik wykona instrukcję DML, jego sesja zostanie niejako „zawieszona”. Zapytanie będzie oczekiwało na wykonanie do
  245.  
  246. momentu kiedy przez użytkownika blokującego dane nie zostaną odblokowane.
  247.  
  248. Klauzula NOWAIT powoduje, że użytkownik nie będzie oczekiwał „zawieszony” na zwolnienie blokady, a otrzymam informację że w tej chwili wykonanie operacji
  249.  
  250. nie jest możliwe.
  251.  
  252.  
  253. Przykład
  254. --------
  255.  
  256. SQL> DELETE FROM Product;
  257. INSERT INTO Product (product_id, order_id, product_name, price) VALUES (301, 1, 'product_1', 100);
  258. INSERT INTO Product (product_id, order_id, product_name, price) VALUES (302, 1, 'product_2', 100);
  259. INSERT INTO Product (product_id, order_id, product_name, price) VALUES (303, 1, 'other1', 300);
  260. INSERT INTO Product (product_id, order_id, product_name, price) VALUES (304, 1, 'other2', 400);
  261. COMMIT;
  262.  
  263.  
  264. CREATE OR REPLACE PROCEDURE do_something(p_id NUMBER) IS
  265. row_locked EXCEPTION;
  266. PRAGMA EXCEPTION_INIT(row_locked, -54);
  267. BEGIN
  268. FOR cc IN (SELECT *
  269. FROM Product
  270. WHERE product_id = p_id FOR UPDATE NOWAIT) LOOP
  271. NULL;
  272. END LOOP;
  273. EXCEPTION
  274. WHEN row_locked THEN
  275. raise_application_error(-20001, 'this row is locked...');
  276.  
  277. END do_something;
  278. /
  279.  
  280.  
  281.  
  282.  
  283. Sesja 1
  284.  
  285. SELECT product_id FROM Product WHERE product_id = 301 FOR UPDATE;
  286.  
  287. PRODUCT_ID
  288. ----------
  289. 301
  290.  
  291.  
  292. Sesja 2
  293.  
  294. EXEC do_something(301);
  295.  
  296. BŁĄD w linii 1:
  297. ORA-20001: this row is locked...
  298. ORA-06512: przy "SYSTEM.DO_SOMETHING", linia 12
  299. ORA-06512: przy linia 1
  300.  
  301.  
  302. Sesja 1
  303.  
  304. COMMIT;
  305.  
  306. Zatwierdzanie zostało ukończone.
  307.  
  308.  
  309. Sesja 2
  310. EXEC do_something(301);
  311.  
  312. Procedura PL/SQL została zakończona pomyślnie.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement