Commit 0e0d38d7 by Patryk Czarnik

Przykłady baz danych

parent 89b5d4bd
File added
url=jdbc:postgresql://localhost/hr
user=alx
password=abc123
tcpKeepAlive=true
-- Wykonac jako user postgres (administrator)
-- Pozostale pliki juz jako user alx
DROP DATABASE IF EXISTS hr;
--DROP ROLE IF EXISTS alx;
--CREATE USER alx PASSWORD 'abc123';
CREATE DATABASE hr ENCODING 'utf-8' OWNER alx;
CREATE TABLE regions (
region_id INTEGER CONSTRAINT region_id_nn NOT NULL,
region_name VARCHAR(25),
CONSTRAINT reg_id_pk PRIMARY KEY (region_id)
);
CREATE TABLE countries (
country_id CHAR(2) CONSTRAINT country_id_nn NOT NULL,
country_name VARCHAR(40),
region_id INTEGER,
CONSTRAINT country_c_id_pk PRIMARY KEY (country_id),
CONSTRAINT countr_reg_fk FOREIGN KEY (region_id) REFERENCES regions(region_id)
);
CREATE TABLE locations (
location_id INTEGER,
street_address VARCHAR(40),
postal_code VARCHAR(12),
city VARCHAR(30) CONSTRAINT loc_city_nn NOT NULL,
state_province VARCHAR(25),
country_id CHAR(2),
CONSTRAINT loc_id_pk PRIMARY KEY (location_id),
CONSTRAINT loc_c_id_fk FOREIGN KEY (country_id) REFERENCES countries(country_id)
);
CREATE TABLE departments (
department_id INTEGER,
department_name VARCHAR(100) CONSTRAINT dept_name_nn NOT NULL,
manager_id INTEGER,
location_id INTEGER,
CONSTRAINT dept_id_pk PRIMARY KEY (department_id),
CONSTRAINT dept_loc_fk FOREIGN KEY (location_id) REFERENCES locations (location_id)
) ;
CREATE TABLE jobs (
job_id VARCHAR(10),
job_title VARCHAR(35) CONSTRAINT job_title_nn NOT NULL,
min_salary NUMERIC(8, 2),
max_salary NUMERIC(8, 2),
CONSTRAINT job_id_pk PRIMARY KEY(job_id)
);
CREATE TABLE employees (
employee_id INTEGER,
first_name VARCHAR(25),
last_name VARCHAR(30) CONSTRAINT emp_last_name_nn NOT NULL,
email VARCHAR(30) CONSTRAINT emp_email_nn NOT NULL,
phone_number VARCHAR(20),
hire_date DATE CONSTRAINT emp_hire_date_nn NOT NULL,
job_id VARCHAR(10) CONSTRAINT emp_job_nn NOT NULL,
salary NUMERIC(8, 2),
commission_pct NUMERIC(2, 2),
manager_id INTEGER,
department_id INTEGER,
CONSTRAINT emp_emp_id_pk PRIMARY KEY (employee_id),
CONSTRAINT emp_dept_fk FOREIGN KEY (department_id) REFERENCES departments,
CONSTRAINT emp_job_fk FOREIGN KEY (job_id) REFERENCES jobs (job_id),
CONSTRAINT emp_manager_fk FOREIGN KEY (manager_id) REFERENCES employees,
CONSTRAINT emp_salary_min CHECK (salary > 0),
CONSTRAINT emp_email_uk UNIQUE (email)
);
CREATE TABLE job_history (
employee_id INTEGER CONSTRAINT jhist_employee_nn NOT NULL,
start_date DATE CONSTRAINT jhist_start_date_nn NOT NULL,
end_date DATE CONSTRAINT jhist_end_date_nn NOT NULL,
job_id VARCHAR(10) CONSTRAINT jhist_job_nn NOT NULL,
department_id INTEGER,
CONSTRAINT jhist_date_interval CHECK (end_date > start_date),
CONSTRAINT jhist_emp_id_st_date_pk PRIMARY KEY (employee_id, start_date),
CONSTRAINT jhist_job_fk FOREIGN KEY (job_id) REFERENCES jobs,
CONSTRAINT jhist_emp_fk FOREIGN KEY (employee_id) REFERENCES employees,
CONSTRAINT jhist_dept_fk FOREIGN KEY (department_id) REFERENCES departments
);
COMMENT ON TABLE regions IS 'Regions table that contains region numbers and names. Contains 4 rows; references with the Countries table.';
COMMENT ON COLUMN regions.region_id IS 'Primary key of regions table.';
COMMENT ON COLUMN regions.region_name IS 'Names of regions. Locations are in the countries of these regions.';
COMMENT ON TABLE locations IS
'Locations table that contains specific address of a specific office,
warehouse, and/or production site of a company. Does not store addresses /
locations of customers. Contains 23 rows; references with the
departments and countries tables. ';
COMMENT ON COLUMN locations.location_id IS
'Primary key of locations table';
COMMENT ON COLUMN locations.street_address IS
'Street address of an office, warehouse, or production site of a company.
Contains building number and street name';
COMMENT ON COLUMN locations.postal_code IS
'Postal code of the location of an office, warehouse, or production site
of a company. ';
COMMENT ON COLUMN locations.city IS
'A not null column that shows city where an office, warehouse, or
production site of a company is located. ';
COMMENT ON COLUMN locations.state_province IS
'State or Province where an office, warehouse, or production site of a
company is located.';
COMMENT ON COLUMN locations.country_id IS
'Country where an office, warehouse, or production site of a company is
located. Foreign key to country_id column of the countries table.';
COMMENT ON TABLE departments IS
'Departments table that shows details of departments where employees
work. Contains 27 rows; references with locations, employees, and job_history tables.';
COMMENT ON COLUMN departments.department_id IS
'Primary key column of departments table.';
COMMENT ON COLUMN departments.department_name IS
'A not null column that shows name of a department. Administration,
Marketing, Purchasing, Human Resources, Shipping, IT, Executive, Public
Relations, Sales, Finance, and Accounting. ';
COMMENT ON COLUMN departments.manager_id IS
'Manager_id of a department. Foreign key to employee_id column of employees table. The manager_id column of the employee table references this column.';
COMMENT ON COLUMN departments.location_id IS
'Location id where a department is located. Foreign key to location_id column of locations table.';
COMMENT ON TABLE job_history IS
'Table that stores job history of the employees. If an employee
changes departments within the job or changes jobs within the department,
new rows get inserted into this table with old job information of the
employee. Contains a complex primary key: employee_id+start_date.
Contains 25 rows. References with jobs, employees, and departments tables.';
COMMENT ON COLUMN job_history.employee_id IS
'A not null column in the complex primary key employee_id+start_date.
Foreign key to employee_id column of the employee table';
COMMENT ON COLUMN job_history.start_date IS
'A not null column in the complex primary key employee_id+start_date.
Must be less than the end_date of the job_history table. (enforced by
constraint jhist_date_interval)';
COMMENT ON COLUMN job_history.end_date IS
'Last day of the employee in this job role. A not null column. Must be
greater than the start_date of the job_history table.
(enforced by constraint jhist_date_interval)';
COMMENT ON COLUMN job_history.job_id IS
'Job role in which the employee worked in the past; foreign key to
job_id column in the jobs table. A not null column.';
COMMENT ON COLUMN job_history.department_id IS
'Department id in which the employee worked in the past; foreign key to deparment_id column in the departments table';
COMMENT ON TABLE countries IS
'country table. Contains 25 rows. References with locations table.';
COMMENT ON COLUMN countries.country_id IS
'Primary key of countries table.';
COMMENT ON COLUMN countries.country_name IS
'Country name';
COMMENT ON COLUMN countries.region_id IS
'Region ID for the country. Foreign key to region_id column in the departments table.';
COMMENT ON TABLE jobs IS
'jobs table with job titles and salary ranges. Contains 19 rows.
References with employees and job_history table.';
COMMENT ON COLUMN jobs.job_id IS
'Primary key of jobs table.';
COMMENT ON COLUMN jobs.job_title IS
'A not null column that shows job title, e.g. AD_VP, FI_ACCOUNTANT';
COMMENT ON COLUMN jobs.min_salary IS
'Minimum salary for a job title.';
COMMENT ON COLUMN jobs.max_salary IS
'Maximum salary for a job title';
COMMENT ON TABLE employees IS
'employees table. Contains 107 rows. References with departments,
jobs, job_history tables. Contains a self reference.';
COMMENT ON COLUMN employees.employee_id IS
'Primary key of employees table.';
COMMENT ON COLUMN employees.first_name IS
'First name of the employee. A not null column.';
COMMENT ON COLUMN employees.last_name IS
'Last name of the employee. A not null column.';
COMMENT ON COLUMN employees.email IS
'Email id of the employee';
COMMENT ON COLUMN employees.phone_number IS
'Phone number of the employee; includes country code and area code';
COMMENT ON COLUMN employees.hire_date IS
'Date when the employee started on this job. A not null column.';
COMMENT ON COLUMN employees.job_id IS
'Current job of the employee; foreign key to job_id column of the
jobs table. A not null column.';
COMMENT ON COLUMN employees.salary IS
'Monthly salary of the employee. Must be greater
than zero (enforced by constraint emp_salary_min)';
COMMENT ON COLUMN employees.commission_pct IS
'Commission percentage of the employee; Only employees in sales
department elgible for commission percentage';
COMMENT ON COLUMN employees.manager_id IS
'Manager id of the employee; has same domain as manager_id in
departments table. Foreign key to employee_id column of employees table.
(useful for reflexive joins and CONNECT BY query)';
COMMENT ON COLUMN employees.department_id IS
'Department id where employee works; foreign key to department_id
column of the departments table';
CREATE SEQUENCE locations_seq START WITH 3300 INCREMENT BY 100 MAXVALUE 9900 NO CYCLE;
ALTER TABLE locations ALTER COLUMN location_id SET DEFAULT nextval('locations_seq');
CREATE SEQUENCE departments_seq START WITH 280 INCREMENT BY 10 MAXVALUE 9990 NO CYCLE;
ALTER TABLE departments ALTER COLUMN department_id SET DEFAULT nextval('departments_seq');
CREATE SEQUENCE employees_seq START WITH 207 INCREMENT BY 1 NO CYCLE;
ALTER TABLE employees ALTER COLUMN employee_id SET DEFAULT nextval('employees_seq');
CREATE OR REPLACE VIEW emp_details_view (
employee_id, job_id, manager_id, department_id, location_id, country_id, first_name, last_name, salary, commission_pct, department_name, job_title, city, state_province, country_name, region_name
) AS SELECT e.employee_id,
e.job_id,
e.manager_id,
e.department_id,
d.location_id,
l.country_id,
e.first_name,
e.last_name,
e.salary,
e.commission_pct,
d.department_name,
j.job_title,
l.city,
l.state_province,
c.country_name,
r.region_name
FROM employees e,
departments d,
jobs j,
locations l,
countries c,
regions r
WHERE e.department_id = d.department_id
AND d.location_id = l.location_id
AND l.country_id = c.country_id
AND c.region_id = r.region_id
AND j.job_id = e.job_id;
CREATE INDEX emp_department_ix ON employees(department_id);
CREATE INDEX emp_job_ix ON employees(job_id);
CREATE INDEX emp_manager_ix ON employees(manager_id);
CREATE INDEX emp_name_ix ON employees(last_name, first_name);
CREATE OR REPLACE VIEW szczegoly_pracownika AS
SELECT e.employee_id, e.first_name, e.last_name, e.email, e.phone_number, e.manager_id AS manager_id,
department_id, d.department_name, d.manager_id AS department_manager_id,
location_id, l.street_address, l.city, l.postal_code,
country_id, c.country_name, region_id, r.region_name
FROM employees e
LEFT JOIN jobs j USING (job_id)
LEFT JOIN departments d USING (department_id)
LEFT JOIN locations l USING (location_id)
LEFT JOIN countries c USING (country_id)
LEFT JOIN regions r USING (region_id)
ORDER BY e.employee_id;
CREATE OR REPLACE FUNCTION pensje_dzisiaj() RETURNS void AS $$
DECLARE
pracownik employees%ROWTYPE;
BEGIN
FOR pracownik IN SELECT * FROM employees
LOOP
INSERT INTO salary_history(employee_id, salary, date)
VALUES (pracownik.employee_id, pracownik.salary, current_date);
END LOOP;
END
$$ LANGUAGE plpgsql;
CREATE OR REPLACE PROCEDURE przenies_pracownika(
emp_id employees.employee_id%TYPE,
dep_id employees.department_id%TYPE,
job_id employees.job_id%TYPE
) AS $$
DECLARE
stary employees%ROWTYPE;
data_poczatkowa DATE;
BEGIN
SELECT * FROM employees
WHERE employee_id = emp_id
INTO stary;
IF NOT FOUND THEN
RAISE EXCEPTION 'employee % not found', emp_id;
END IF;
SELECT max(end_date) FROM job_history
WHERE employee_id = emp_id
INTO data_poczatkowa;
IF data_poczatkowa IS NULL
THEN data_poczatkowa := stary.hire_date;
END IF;
INSERT INTO job_history(employee_id, start_date, end_date, job_id, department_id)
VALUES (emp_id, data_poczatkowa, current_date, stary.job_id, stary.department_id);
UPDATE employees SET
department_id = dep_id,
job_id = przenies_pracownika.job_id
WHERE employee_id = emp_id;
END
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION nazwisko_szefa(
emp_id INTEGER
) RETURNS VARCHAR AS $$
DECLARE
wynik VARCHAR;
BEGIN
SELECT first_name || ' ' || last_name
INTO wynik
FROM employees
WHERE employee_id = (SELECT manager_id FROM employees WHERE employee_id = emp_id);
RETURN wynik;
END
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION statystyki_departamentu(
dep_id IN INTEGER,
emp_count OUT INTEGER,
avg_salary OUT NUMERIC,
min_salary OUT NUMERIC,
max_salary OUT NUMERIC
) RETURNS record AS $$
BEGIN
SELECT count(employee_id), avg(salary), min(salary), max(salary)
INTO emp_count, avg_salary, min_salary, max_salary
FROM employees
WHERE department_id = dep_id;
END
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION zarabiajacy_wiecej_niz(emp_id INTEGER)
RETURNS SETOF employees AS $$
DECLARE
the_salary NUMERIC;
BEGIN
SELECT salary INTO the_salary FROM employees WHERE employee_id = emp_id;
RETURN QUERY
SELECT * FROM employees WHERE salary > the_salary ORDER BY salary ASC;
END
$$ LANGUAGE plpgsql;
DROP FUNCTION zarabiajacy_wiecej_niz;
DROP FUNCTION statystyki_departamentu;
DROP FUNCTION nazwisko_szefa;
DROP PROCEDURE przenies_pracownika;
DROP FUNCTION pensje_dzisiaj;
DROP INDEX emp_name_ix;
DROP INDEX emp_manager_ix;
DROP INDEX emp_job_ix;
DROP INDEX emp_department_ix;
DROP VIEW emp_details_view;
DROP VIEW szczegoly_pracownika;
DROP TABLE job_history;
DROP TABLE employees;
DROP TABLE jobs;
DROP TABLE departments;
DROP TABLE locations;
DROP TABLE countries;
DROP TABLE regions;
DROP SEQUENCE employees_seq;
DROP SEQUENCE departments_seq;
DROP SEQUENCE locations_seq;
set PG_HOME=C:\Program Files\PostgreSQL\16
set Path=%Path%;%PG_HOME%\bin
psql -h localhost -p 5432 -d postgres -U postgres -f 0-admin.sql
psql -h localhost -p 5432 -d hr -U alx -f wgraj_hr.sql
pause
SET client_encoding = 'UTF8';
\i 1-hr-create-tabele.sql
\i 2-hr-create-dodatki.sql
\i 3-hr-insert.sql
\i 4-hr-moje-dodatki.sql
CREATE TABLE skocznie (
id_skoczni integer primary key,
miasto text,
kraj_s text,
nazwa text,
k integer,
sedz integer
);
CREATE TABLE trenerzy (
kraj char(3) primary key,
imie_t text,
nazwisko_t text,
data_ur_t date
);
CREATE TABLE zawodnicy (
id_skoczka integer primary key,
imie text,
nazwisko text,
kraj char(3),
data_ur date,
wzrost integer,
waga integer
);
CREATE TABLE zawody (
id_zawodow integer primary key,
id_skoczni integer,
data date
);
INSERT INTO skocznie VALUES (1, 'Zakopane', 'POL', 'Wielka Krokiew', 120, 134);
INSERT INTO skocznie VALUES (2, 'Garmisch-Partenkirchen', 'GER', 'Wielka Skocznia Olimpijska', 115, 125);
INSERT INTO skocznie VALUES (4, 'Oberstdorf', 'GER', 'Skocznia Heiniego Klopfera', 185, 211);
INSERT INTO skocznie VALUES (3, 'Oberstdorf', 'GER', 'Grosse Schattenberg', 120, 134);
INSERT INTO skocznie VALUES (5, 'Willingen', 'GER', 'Grosse Muhlenkopfschanze', 130, 145);
INSERT INTO skocznie VALUES (6, 'Kuopio', 'FIN', 'Puijo', 120, 131);
INSERT INTO skocznie VALUES (7, 'Lahti', 'FIN', 'Salpausselka', 116, 128);
INSERT INTO skocznie VALUES (8, 'Trondheim', 'NOR', 'Granasen', 120, 132);
INSERT INTO trenerzy VALUES ('AUT', 'Alexander', 'Pointner', NULL);
INSERT INTO trenerzy VALUES ('FIN', 'Tommi', 'Nikunen', NULL);
INSERT INTO trenerzy VALUES ('NOR', 'Mika', 'Kojonkoski', '1963-04-19');
INSERT INTO trenerzy VALUES ('POL', 'Heinz', 'Kuttin', '1971-01-05');
INSERT INTO trenerzy VALUES ('GER', 'Wolfang', 'Steiert', '1963-04-19');
INSERT INTO trenerzy VALUES ('JPN', 'Hirokazu', 'Yagi', NULL);
INSERT INTO zawodnicy VALUES (1, 'Adam', 'MAŁYSZ', 'POL', '1977-12-03', 169, 60);
INSERT INTO zawodnicy VALUES (2, 'Marcin', 'BACHLEDA', 'POL', '1982-09-04', 166, 56);
INSERT INTO zawodnicy VALUES (3, 'Robert', 'MATEJA', 'POL', '1974-10-05', 180, 63);
INSERT INTO zawodnicy VALUES (4, 'Alexander', 'HERR', 'GER', '1978-10-04', 173, 65);
INSERT INTO zawodnicy VALUES (5, 'Stephan', 'HOCKE', 'GER', '1983-10-20', 178, 59);
INSERT INTO zawodnicy VALUES (6, 'Martin', 'SCHMITT', 'GER', '1978-01-29', 181, 64);
INSERT INTO zawodnicy VALUES (7, 'Michael', 'UHRMANN', 'GER', '1978-09-09', 184, 64);
INSERT INTO zawodnicy VALUES (8, 'Georg', 'SPAETH', 'GER', '1981-02-24', 187, 68);
INSERT INTO zawodnicy VALUES (9, 'Matti', 'HAUTAMAEKI', 'FIN', '1981-07-14', 174, 57);
INSERT INTO zawodnicy VALUES (10, 'Tami', 'KIURU', 'FIN', '1976-09-13', 183, 59);
INSERT INTO zawodnicy VALUES (11, 'Janne', 'AHONEN', 'FIN', '1977-05-11', 184, 67);
INSERT INTO zawodnicy VALUES (12, 'Martin', 'HOELLWARTH', 'AUT', '1974-04-13', 182, 67);
INSERT INTO zawodnicy VALUES (13, 'Thomas', 'MORGENSTERN', 'AUT', '1986-10-30', 174, 57);
INSERT INTO zawodnicy VALUES (15, 'Tommy', 'INGEBRIGTSEN', 'NOR', '1977-08-08', 179, 56);
INSERT INTO zawodnicy VALUES (16, 'Bjoern-Einar', 'ROMOEREN', 'NOR', '1981-04-01', 182, 63);
INSERT INTO zawodnicy VALUES (17, 'Roar', 'LJOEKELSOEY', 'NOR', '1976-05-31', 175, 62);
INSERT INTO zawodnicy VALUES (14, 'Alan', 'ALBORN', 'USA', '1980-12-13', 177, 57);
INSERT INTO zawody VALUES (1, 1, '2007-01-23');
INSERT INTO zawody VALUES (2, 7, '2006-11-15');
INSERT INTO zawody VALUES (3, 3, '2006-12-26');
SELECT * FROM zawodnicy;
SELECT * FROM zawodnicy FULL JOIN trenerzy USING(kraj);
package bazy_danych.podstawy;
import java.math.BigDecimal;
import java.sql.*;
// JDBC Java Database Connectivity
public class OdczytajOsoby {
public static void main(String[] args) {
try(Connection c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/alx",
"alx", "abc123")) {
System.out.println("Mam połączenie: " + c);
try(PreparedStatement stmt = c.prepareStatement("SELECT * FROM osoby");
ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
int id = rs.getInt(1); // albo rs.getInt("id");
String imie = rs.getString("imie");
String nazwisko = rs.getString("nazwisko");
Date dataUr = rs.getDate("data_ur");
BigDecimal pensja = rs.getBigDecimal("pensja");
System.out.printf("%d: %s %s, ur. %s, pensja: %s%n", id, imie, nazwisko, dataUr, pensja);
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
package bazy_danych.podstawy;
import java.math.BigDecimal;
import java.sql.*;
public class Pracownicy {
public static void main(String[] args) {
try(Connection c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/hr",
"alx", "abc123")) {
try(PreparedStatement stmt = c.prepareStatement("SELECT * FROM employees")) {
try(ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
String imie = rs.getString("first_name");
String nazwisko = rs.getString("last_name");
String job = rs.getString("job_id");
BigDecimal pensja = rs.getBigDecimal("salary");
System.out.printf("%s %s (%s) zarabia %s%n", imie, nazwisko, job, pensja);
}
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
package bazy_danych.podstawy;
import javax.swing.*;
import java.math.BigDecimal;
import java.sql.*;
// Zadanie: niech program wypisuje tylko tych pracowników, którzy mają podane job_id
// Wada tego rozwiązania: NISKA WYDAJNOŚĆ
// Serwer odczytuje wszystkie rekordy z dysku
// wszystkie rekordy są przesyłanie przez sieć
// wszystkie rekordy są odbieranie i przeglądane przez program w Javie.
public class PracownicyWedlugJob1 {
public static void main(String[] args) {
try(Connection c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/hr", "alx", "abc123")) {
String szukanyJob = JOptionPane.showInputDialog("Podaj nazwę stanowiska", "IT_PROG");
try(PreparedStatement stmt = c.prepareStatement("SELECT * FROM employees")) {
try(ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
String job = rs.getString("job_id");
if(job.equals(szukanyJob)) {
String imie = rs.getString("first_name");
String nazwisko = rs.getString("last_name");
BigDecimal pensja = rs.getBigDecimal("salary");
System.out.printf("%s %s (%s) zarabia %s%n", imie, nazwisko, job, pensja);
}
}
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
package bazy_danych.podstawy;
import javax.swing.*;
import java.math.BigDecimal;
import java.sql.*;
// Zadanie: niech program wypisuje tylko tych pracowników, którzy mają podane job_id
// Niech program wypisuje tylko tych pracowników, którzy mają podane job_id.
// Ta wersja jest niebezpieczna - umożliwia użytkownikowi dopisanie dowolnego kodu do zapytania.
// = "SQL Injection"
// '; UPDATE employees SET salary = 99000; SELECT '
// '; DROP TABLE employees CASCADE; SELECT '
public class PracownicyWedlugJob2 {
public static void main(String[] args) {
try(Connection c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/hr", "alx", "abc123")) {
String szukanyJob = JOptionPane.showInputDialog("Podaj nazwę stanowiska", "IT_PROG");
try(PreparedStatement stmt = c.prepareStatement("SELECT * FROM employees WHERE job_id = '" + szukanyJob +"'")) {
System.out.println(stmt);
try(ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
String job = rs.getString("job_id");
String imie = rs.getString("first_name");
String nazwisko = rs.getString("last_name");
BigDecimal pensja = rs.getBigDecimal("salary");
System.out.printf("%s %s (%s) zarabia %s%n", imie, nazwisko, job, pensja);
}
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
package bazy_danych.podstawy;
import javax.swing.*;
import java.math.BigDecimal;
import java.sql.*;
// Zadanie: niech program wypisuje tylko tych pracowników, którzy mają podane job_id
// Rozwiązanie poprawne:
// - Dzięki WHERE to serwer wybiera tylko te rekordy, które spełniają warunek.
// * Jeśli dla kolumny jest zdefiniowany indeks, to serwer bardzo sprawnie odczyta z dysku tylko te rekordy, które mają sens (dla dużych danych to jest olbrzymie przyspieszenie)
// * Nawet gdyby nie było indeksu, to sprawdzanie warunku po stronie serwera zmniejsza transfer i obciążenie naszej aplikacji klienckiej.
// - Dzięki podstawianiu parametrów za pomocą ? jest to bezpieczne - nie ma możliwości SQL Injection (oczywiście o ile twórcy sterownika postgresql-jdbc dobrze go napisali...)
public class PracownicyWedlugJob3 {
public static void main(String[] args) {
try(Connection c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/hr", "alx", "abc123")) {
String szukanyJob = JOptionPane.showInputDialog("Podaj nazwę stanowiska", "IT_PROG");
try(PreparedStatement stmt = c.prepareStatement("SELECT * FROM employees WHERE job_id = ?")) {
stmt.setString(1, szukanyJob);
System.out.println(stmt);
try(ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
String job = rs.getString("job_id");
String imie = rs.getString("first_name");
String nazwisko = rs.getString("last_name");
BigDecimal pensja = rs.getBigDecimal("salary");
System.out.printf("%s %s (%s) zarabia %s%n", imie, nazwisko, job, pensja);
}
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class P00_TestPolaczenia {
public static void main(String[] args) {
try (Connection c = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/hr",
"kurs",
"abc123")) {
System.out.println("Udało się połączyć: " + c);
System.out.println(c.getClientInfo());
System.out.println(c.getMetaData().getDatabaseProductName());
try (Statement stmt = c.createStatement()) {
final String sql = "SELECT * FROM employees";
try (ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
System.out.print(rs.getString("first_name"));
System.out.print(" ");
System.out.println(rs.getString("last_name"));
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
public class P01_Odczyt_Statement {
public static void main(String[] args) {
try {
// W tej wersji zamykam połączenie za pomocą jawnego close()
Connection c = DriverManager.getConnection(Ustawienia.URL,Ustawienia.USER,Ustawienia.PASSWD);
System.out.println("Udało się połączyć: " + c);
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM employees");
while (rs.next()) {
// Wartości z kolumn można odczytywać wg numerów (numeracja od 1)
// Do różnych typów danych mamy odpowiednie metody getXXX()
int id = rs.getInt(1);
String firstName = rs.getString(2);
String lastName = rs.getString(3);
// Wartości z kolumn można też odczytywać wg nazw (lub aliasów)
String jobId = rs.getString("job_id");
BigDecimal salary = rs.getBigDecimal("salary");
java.sql.Date date = rs.getDate("hire_date");
LocalDate localDate = date.toLocalDate();
System.out.printf("%d %s %s %s %s %s%n", id, firstName, lastName, jobId, salary, date);
}
// również obiekty Statement oraz ResultSet należy zamykać
// ponieważ mogą się z nimi wiązać zasoby trzymane po stronie serwera bazy danych
rs.close();
System.out.println("\n----------------------\n");
// Ten sam Statement może być użyty do innego zapytania.
rs = stmt.executeQuery("SELECT city, country_id FROM locations ORDER BY 2, 1");
while (rs.next()) {
System.out.printf("%s (%s)%n", rs.getString(1), rs.getString(2));
}
rs.close();
stmt.close();
c.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
public class P02_Odczyt_Try {
public static void main(String[] args) {
// W tej wersji zamykaniem połączenia i innych zasobów zajmuje się try-with-resources
try(Connection c = DriverManager.getConnection(Ustawienia.URL,Ustawienia.USER,Ustawienia.PASSWD);
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM employees")) {
while (rs.next()) {
// Wartości z kolumn można odczytywać wg numerów (numeracja od 1)
// Do różnych typów danych mamy odpowiednie metody getXXX()
int id = rs.getInt(1);
String firstName = rs.getString(2);
String lastName = rs.getString(3);
// Wartości z kolumn można też odczytywać wg nazw (lub aliasów)
String jobId = rs.getString("job_id");
BigDecimal salary = rs.getBigDecimal("salary");
Date date = rs.getDate("hire_date");
LocalDate localDate = date.toLocalDate();
System.out.printf("%d %s %s %s %s %s%n", id, firstName, lastName, jobId, salary, date);
}
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("Koniec programu");
}
}
package bazy_danych.postgresql;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
public class P03_Odczyt_PreparedStatement {
public static void main(String[] args) {
// W tej wersji zamykniem połączenia i innych zasobów zajmuje się try-with-resources
try (Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
// Dzięki rozdzielenieu do osobnych try mogę pomiędzy nimi wpisywać inne instrukcje
System.out.println("Otwarto połączenie " + c);
c.setAutoCommit(false);
c.setReadOnly(true);
final String sql = "SELECT * FROM employees ORDER BY employee_id";
try (PreparedStatement stmt = c.prepareStatement(sql)) {
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
int id = rs.getInt(1);
String firstName = rs.getString(2);
String lastName = rs.getString(3);
String jobId = rs.getString("job_id");
BigDecimal salary = rs.getBigDecimal("salary");
Date date = rs.getDate("hire_date");
LocalDate localDate = date.toLocalDate();
System.out.printf("%d %s %s %s %s %s%n", id, firstName, lastName, jobId, salary, date);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import javax.swing.*;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
public class P04_Odczyt_Sparametryzowany {
public static void main(String[] args) {
String kogoSzukac = JOptionPane.showInputDialog("Podaj kod stanowiska, np. IT_PROG");
try (Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
System.out.println("Otwarto połączenie " + c);
// również stosowanie traksancji oraz oznaczanie sesji jako readonly jeśli nie planujemy zmian są dodatkowymi zabezpieczeniami przed skutkami SQL injection
c.setAutoCommit(false);
c.setReadOnly(true);
final String sql = "SELECT * FROM employees WHERE job_id = ? ORDER BY employee_id";
try (PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setString(1, kogoSzukac);
System.out.println("Zapytanie do wykonania: " + stmt);
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
int id = rs.getInt(1);
String firstName = rs.getString(2);
String lastName = rs.getString(3);
String jobId = rs.getString("job_id");
BigDecimal salary = rs.getBigDecimal("salary");
Date date = rs.getDate("hire_date");
LocalDate localDate = date.toLocalDate();
System.out.printf("%d %s %s %s %s %s%n", id, firstName, lastName, jobId, salary, date);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class P05_ProstyUpdate {
public static void main(String[] args) {
String sql = "UPDATE employees SET salary = salary + ? WHERE job_id = ?" ;
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setInt(1, 333);
stmt.setString(2, "IT_PROG");
int ile = stmt.executeUpdate(); // uwaga, tego używamy także dla insert czy delete
// Dokładnie mówiąc: ilu wierszy dotyczyło zapytanie.
// W tym programie nie są używane transakcje (inaczej mówiąc: autoCommit == true)
// więc od razu zmiany są zapisywane trwale na serwerze.
System.out.println("Zaktualizowano " + ile + " wierszy");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import javax.swing.*;
import java.math.BigDecimal;
import java.sql.*;
public class P06_Transakcja {
public static void main(String[] args) {
try (Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
c.setAutoCommit(false);
c.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); // cudze zmiany widzimy dopiero wtedy, gdy zostaną zakomitowane
// c.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); // nie widzimy cudzych zmian w czasie traksakcji, kolejne selecty zwracają te same wartości (o ile sami nie edytujemy)
// c.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); // nasze zmiany nie zamażą cudzych zmian - ale możemy dostać wyjątek gdy próbujemy zmeiniać rekordy
// c.setReadOnly(true); // tutaj nie ma sensu, ale może mieć sens:
JOptionPane.showMessageDialog(null, "Połączyliśmy się i ustawiliśmy transakcję...");
String kogoSzukac = JOptionPane.showInputDialog("Podaj kod stanowiska:");
double srednia1 = sredniaPensja(c, kogoSzukac);
JOptionPane.showMessageDialog(null, "Średnia przed zmianą: " + srednia1);
BigDecimal podwyzka = new BigDecimal(JOptionPane.showInputDialog("Podaj kwotę podwyżki:"));
int ile = podwyzka(c, podwyzka, kogoSzukac);
double srednia2 = sredniaPensja(c, kogoSzukac);
JOptionPane.showMessageDialog(null, ile + "rekordów zmienionych.\nŚrednia po zmianie: " + srednia2);
int wybor = JOptionPane.showConfirmDialog(null, "Czy zapisać zmiany?");
String coSieStalo;
switch (wybor) {
case JOptionPane.YES_OPTION:
c.commit();
coSieStalo = "commit";
break;
case JOptionPane.NO_OPTION:
c.rollback();
coSieStalo = "rollback";
break;
default:
coSieStalo = "cancel";
// Cancel - nie robimy nic
}
double srednia3 = sredniaPensja(c, kogoSzukac);
JOptionPane.showMessageDialog(null, "Średnia po " +coSieStalo +": " + srednia3);
JOptionPane.showMessageDialog(null, "Rozłączamy się...");
} catch (SQLException e) {
e.printStackTrace();
}
}
private static double sredniaPensja(Connection c, String jobId) {
final String sql2 = "SELECT avg(salary) FROM employees WHERE job_id = ?";
try(PreparedStatement stmt2 = c.prepareStatement(sql2)) {
stmt2.setString(1, jobId);
try(ResultSet rs = stmt2.executeQuery()) {
if(rs.next()) {
return rs.getDouble(1);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
private static int podwyzka(Connection c, BigDecimal zmiana, String jobId) {
String sql = "UPDATE employees SET salary = salary + ? WHERE job_id = ?";
try(PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setBigDecimal(1, zmiana);
stmt.setString(2, jobId);
int ile = stmt.executeUpdate();
return ile;
} catch (SQLException e) {
e.printStackTrace();
return 0;
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class P07_GenerowaneId {
/* W abzach danych często stosowane są automatycznie generowane klucze. Gdy wykomnujemy polecenie INSERT nie wymieniając kolumny z kluczem,
* jego wartość jest generowana automatycznie (z sekwencji lub w oparciu o specjalny typ kolumny).
* Ale aplikacja zwykle potrzebuje poznać to ID, aby móc odwoływać się do tego rekordu w dalszej części programu.
* JDBC oferuje mechanizm, w którym przed wykonaniem operacji INSERT w obiekcie Statement rejestruje się automatycznie generowane kolumny,
* a po wykonaniu polecenia można pobrać ich wartości (jako ResultSet).
* W praktyce chodzi o takie kolumny, jak autoinkrementowane ID (przede wszystkim), czas utworzenia rekordu, czasami inne wartości domyślne.
* Tu dodatkowo używam state_province, co jest o tyle nieciekawe, że tam po prostu będzie null,
* ale po prostu pokazuję, że tych pól można podać więcej niż jedno.
*/
public static void main(String[] args) {
// Tablica nazw kolumn, których wartości są wstawiane automatycznie.
// Zamiast nazw mogą być też numery (wtedy tablica intów).
String[] polaGenerowane = {"location_id", "state_province"};
String sql = "INSERT INTO locations(street_address, postal_code, city, country_id) VALUES(?, ?, ?, ?)";
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
PreparedStatement stmt = c.prepareStatement(sql, polaGenerowane)) {
stmt.setString(1, "Nowa z " + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:SS")));
stmt.setString(2, "01-321");
stmt.setString(3, "Warszawa");
stmt.setString(4, "US");
int ile = stmt.executeUpdate();
System.out.println("Wstawiono " + ile + " rekord"); // powinno być 1
// odcyt wartości wygenerowanych pól
try(ResultSet rsGen = stmt.getGeneratedKeys()) {
if(rsGen.next()) {
int id = rsGen.getInt(1);
String state = rsGen.getString(2);
System.out.println("wygenerowane wartości pól: " + id + ", " + state);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P08a_ModyfikacjaPoprzezWynik {
public static void main(String[] args) {
int limit = 100;
final String sql = "SELECT * FROM departments WHERE department_id < ? ORDER BY department_id";
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
try(PreparedStatement stmt = c.prepareStatement(sql,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
stmt.setInt(1, limit);
try(ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) { }
int id = rs.getInt(1);
String staraNazwa = rs.getString(2);
String nowaNazwa = staraNazwa + " *";
System.out.printf("%3d %s → %s\n", id, staraNazwa, nowaNazwa);
rs.updateString(2, nowaNazwa);
//rs.updateString("department_name", nowaNazwa);
rs.updateRow();
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P08b_ModyfikacjaPoprzezWynik_WTransakcji {
public static void main(String[] args) {
final String sql = "SELECT * FROM departments WHERE department_id < ? ORDER BY department_id";
int limit = 100;
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
c.setAutoCommit(false); // przejście w tryb transakcji
try(PreparedStatement stmt = c.prepareStatement(sql,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE)) {
stmt.setInt(1, limit);
try(ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
try {
Thread.sleep(500);
} catch (InterruptedException e) { }
int id = rs.getInt(1);
String staraNazwa = rs.getString(2);
String nowaNazwa = staraNazwa + " #";
System.out.printf("%3d %s → %s\n", id, staraNazwa, nowaNazwa);
rs.updateString(2, nowaNazwa);
rs.updateRow();
}
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
c.commit();
System.out.println("COMMIT");
//c.rollback();
//System.out.println("ROLLBACK");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P09_DowolnaKolejnoscResultSet {
public static void main(String[] args) {
final String sql = "SELECT employee_id, first_name, last_name FROM employees ORDER BY employee_id";
int[] pozycje = {1, 100, 3, 5, 500, 30, 1, 3};
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
// Aby przewijanie wyników (takie operacje jak absolute() czy previous()) było możliwe,
// należy utworzyć zapytanie typu
// TYPE_SCROLL_INSENSITIVE - wyniki nie są już aktualizowane w trakcie przeglądania; dwa razy odwiedzając ten sam rekord zobaczymy te same dane
// TYPE_SCROLL_SENSITIVE - wyniki są wrażliwe na zmiany robione na tabelach, dane mogą zmienić się w trakcie
// TYPE_FORWARD_ONLY - domyślny, w ogóle nie umożliwia przewijania, tylko rs.next()
try(PreparedStatement stmt = c.prepareStatement(sql,
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
// możemy sterować ilością rekordów pobieranych jednorazowo przez sieć
// stmt.setFetchSize(20);
try(ResultSet rs = stmt.executeQuery()) {
// Metody z "is" w nazwie tylko sprawdzają położenie, ale go nie zmieniają.
if(rs.isBeforeFirst()) {
System.out.println("before first");
}
if(rs.isFirst()) {
System.out.println("first");
}
if(rs.isAfterLast()) {
System.out.println("after last");
}
if(rs.isLast()) {
System.out.println("first");
}
// rs.beforeFirst(); // ustawia pozycję na taką, to jest domyślne ustawienie na samym początku, przed while(rs.next())
// rs.afterLast(); // ustawia pozycję na taką
// rs.first(); // ustawia na pierwszy rekord (zwraca false jeśli takiego nie ma)
// rs.last(); // ustawia na ostatni rekord (zwraca false jeśli takiego nie ma)
// rs.absolute(nr); // przechodzi do konkretnego numeru wiersza
// rs.relative(offset); // przesuwa się o tyle wględem pozycji bieżącej
// rs.next(); // przesuwa do następnego (jak relative(1))
// rs.previous(); // przesuwa do poprzedniego (jak relative(-1))
for(int poz : pozycje) {
if(rs.absolute(poz)) {
int id = rs.getInt(1);
String imie = rs.getString(2);
String nazwisko = rs.getString(3);
System.out.printf("\npoz %3d: %d %s %s\n", poz, id, imie, nazwisko);
if(rs.previous()) {
nazwisko = rs.getString(3);
System.out.printf(" ... a poprzedni ma na nazwisko %s\n", nazwisko);
}
if(rs.relative(2)) {
nazwisko = rs.getString(3);
System.out.printf(" ... a następny ma na nazwisko %s\n", nazwisko);
}
} else {
System.out.printf("\npoz %3d - nie ma takiej pozycji\n", poz);
}
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class P10_Batch {
public static void main(String[] args) {
int ID = 5000;
int ILE = 1000;
final String sql = "INSERT INTO locations(location_id, street_address, postal_code, city, country_id)"
+ " VALUES(?,?,?,?,?)";
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
PreparedStatement stmt = c.prepareStatement(sql)) {
c.setAutoCommit(false); // wyłączamy automatyczne commitowanie - przechodzimy w tryb traksakcji
System.out.println("start");
long poczatek = System.currentTimeMillis();
for(int i=0; i<ILE; i++) {
stmt.setInt(1, ID + i);
stmt.setString(2, "Jasna 23 " + i);
stmt.setString(3, "01-234");
stmt.setString(4, "Warszawa");
stmt.setString(5, "UK");
stmt.addBatch();
if(i % 50 == 0) {
System.out.println();
}
System.out.print(".");
System.out.flush();
}
System.out.print("\n***");
// Wykonanie wszystkich poleceń zapamiętanych w batchu
stmt.executeBatch();
//c.rollback();
c.commit();
long koniec = System.currentTimeMillis();
System.out.println("\n\nGotowe, czas = " + (koniec - poczatek) + " ms");
} catch (SQLException e) {
System.err.println("Błąd podczas łączenia albo wykonywania SQL");
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class P10_Batch_wersja_bez_batch_do_porownania {
public static void main(String[] args) {
int ID = 4000;
int ILE = 1000;
final String sql = "INSERT INTO locations(location_id, street_address, postal_code, city, country_id)"
+ " VALUES(?,?,?,?,?)";
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
PreparedStatement stmt = c.prepareStatement(sql)) {
c.setAutoCommit(false); // wyłączamy automatyczne commitowanie - przechodzimy w tryb traksakcji
System.out.println("start");
long poczatek = System.currentTimeMillis();
for(int i=0; i<ILE; i++) {
stmt.setInt(1, ID + i);
stmt.setString(2, "Jasna 14/16a lok. " + i);
stmt.setString(3, "01-234");
stmt.setString(4, "Warszawa");
stmt.setString(5, "UK");
stmt.executeUpdate();
if(i % 50 == 0) {
System.out.println();
}
System.out.print(".");
System.out.flush();
}
System.out.print("\n***");
//c.rollback();
c.commit();
long koniec = System.currentTimeMillis();
System.out.println("\n\nGotowe, czas = " + (koniec - poczatek) + " ms");
} catch (SQLException e) {
System.err.println("Błąd podczas łączenia albo wykonywania SQL");
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
public class P11_Metadane {
/* Nawet nie wiedząc jaka jest struktura bazy danych, można te informacje odczytać z połączenia */
public static void main(String[] args) {
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
System.out.println("Otwarto połączenie. c = " + c);
DatabaseMetaData dbMetaData = c.getMetaData();
System.out.println(dbMetaData.getDatabaseProductName());
System.out.println(dbMetaData.getDatabaseMajorVersion()
+ "." + dbMetaData.getDatabaseMinorVersion());
System.out.println();
try(ResultSet tables = dbMetaData.getTables(null, "public", null, null)) {
wypiszTabele(tables);
}
System.out.println("\n\nNormalna tabela:");
try(ResultSet rs = c.createStatement().executeQuery("SELECT * FROM jobs")) {
wypiszTabele(rs);
}
System.out.println();
try(ResultSet rs = c.createStatement().executeQuery("SELECT * FROM departments JOIN locations USING(location_id)")) {
wypiszTabele(rs);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
private static void wypiszTabele(ResultSet rs) throws SQLException {
// Odczytanie "metadanych wyniku"
ResultSetMetaData rsMetaData = rs.getMetaData();
final int n = rsMetaData.getColumnCount();
System.out.println("Wynik ma " + n + " kolumn:");
for(int i = 1; i <= n; i++) {
System.out.printf("%-30s", rsMetaData.getColumnName(i));
}
System.out.println();
for(int i = 1; i <= n; i++) {
System.out.printf("%-30s", rsMetaData.getColumnType(i));
}
System.out.println();
for(int i = 1; i <= n; i++) {
System.out.printf("%-30s", rsMetaData.getColumnTypeName(i));
}
System.out.println();
while(rs.next()) {
for(int i = 1; i <= n; i++) {
System.out.printf("%-30s", rs.getString(i));
}
System.out.println();
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class P12_MultiResult {
public static void main(String[] args) {
try (Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD)) {
try (Statement stmt = c.createStatement()) {
// Kilka zapytań w jednym stringu
String sql = "SELECT * FROM countries;"
+ " SELECT * FROM jobs;"
+ " SELECT first_name, last_name FROM employees";
if(stmt.execute(sql)) // jeśli jest pierwszy ResultSet
do {
try (ResultSet rs = stmt.getResultSet()) {
System.out.println("\n###########################\nKolejne wyniki:");
while (rs.next()) {
System.out.print(rs.getString(1));
System.out.print(" ");
System.out.println(rs.getString(2));
}
}
// sprawdzam czy jest jeszcze jakiś kolejny ResultSet i jeśli tak, ponawiam wypisywanie
} while (stmt.getMoreResults());
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class P14a_Procedura_BrakWyniku {
// Przykład wywołania "procedury składowanej" - takie rzeczy można tworzyć w bazach Oracle (PL/SQL), PostgreSQL (odmiana PL/SQL, ale także C i Python), MS SQL Server (T-SQL)
// Ta procedura przyjmuje tylko parametry typu IN i nie zwraca wyniku. W kolejnych plikach przykłady innych sytuacji.
public static void main(String[] args) {
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
CallableStatement stmt = c.prepareCall("CALL przenies_pracownika(?,?,?)")) {
stmt.setInt(1, 112);
stmt.setInt(2, 60);
stmt.setString(3, "IT_PROG");
stmt.execute();
System.out.println("Wykonane");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.math.BigDecimal;
import java.sql.*;
import java.util.Scanner;
public class P14b_Procedura_ParametryOut {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
System.out.print("Podaj numer departamentu: ");
int nrDep = sc.nextInt();
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
CallableStatement stmt = c.prepareCall("{CALL statystyki_departamentu(?,?,?,?,?)}")) {
// parametrom IN ustawiamy wartości
stmt.setInt(1, nrDep);
// parametry OUT należy zarejestrować przed wykonaniem zapytania
stmt.registerOutParameter(2, Types.INTEGER);
stmt.registerOutParameter(3, Types.DECIMAL);
stmt.registerOutParameter(4, Types.DECIMAL);
stmt.registerOutParameter(5, Types.DECIMAL);
stmt.executeUpdate();
// odebranie wartości wynikowych
int count = stmt.getInt(2);
BigDecimal avg = stmt.getBigDecimal(3);
BigDecimal min = stmt.getBigDecimal(4);
BigDecimal max = stmt.getBigDecimal(5);
System.out.printf("Statystyki departamentu %d: cnt = %d, avg = %s, min = %s, max = %s%n",
nrDep, count, avg, min, max);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Scanner;
public class P14c_Procedura_OdczytWartosciSkalarnej {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
System.out.print("Podaj numer pracownika: ");
int nr = sc.nextInt();
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
CallableStatement stmt = c.prepareCall("{?= call nazwisko_szefa(?)}")) {
stmt.setInt(2, nr);
stmt.registerOutParameter(1, Types.VARCHAR);
System.out.println(stmt);
stmt.executeUpdate();
String nazwisko = stmt.getString(1);
if(nazwisko == null) {
System.out.println("Nie ma szefa");
} else {
System.out.println("Szef ma na nazwisko: " + nazwisko);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
import java.util.Scanner;
public class P14d_Procedura_OdczytTabeli {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
System.out.print("Podaj numer pracownika: ");
int nr = sc.nextInt();
try(Connection c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
CallableStatement stmt = c.prepareCall("{call zarabiajacy_wiecej_niz(?)}")) {
stmt.setInt(1, nr);
System.out.println(stmt);
try (ResultSet rs = stmt.executeQuery()) {
System.out.println("Pracownicy zarabiający więcej:");
while (rs.next()) {
int id = rs.getInt(1);
String firstName = rs.getString(2);
String lastName = rs.getString(3);
String jobId = rs.getString("job_id");
BigDecimal salary = rs.getBigDecimal("salary");
Date date = rs.getDate("hire_date");
LocalDate localDate = date.toLocalDate();
System.out.printf("%d %s %s %s %s %s%n", id, firstName, lastName, jobId, salary, date);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P15_Url {
public static void main(String[] args) throws SQLException {
// Parametry zapytania można przekazać też w URL-u.
// W tym także użytkownika i hasło.
// Parametr tcpKeepAlive niczemu konkretnemu tu nie służy - jest tylko przykładem,
// że sterowniki JDBC mogą posiadać dodatkowe parametry niestandardowe.
// W SQL Server parametry rozdziela się średnikami, np user=ala;password=kot
String url = "jdbc:postgresql://localhost/hr?user=kurs&password=abc123&tcpKeepAlive=true";
String name = "Steven";
String last = "King";
Connection c = DriverManager.getConnection(url);
c.setAutoCommit(false);
PreparedStatement stmt = c.prepareStatement("SELECT first_name,last_name FROM EMPLOYEES "
+ "WHERE first_name = ?");
stmt.setString(1, name);
stmt.setFetchSize(10);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.print("Wynik: ");
System.out.print(rs.getString(1) + " ");
System.out.println(rs.getString(2));
}
stmt.setFetchSize(0);
rs.close();
stmt.close();
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class P16a_Property {
// Parametr tcpKeepAlive niczemu konkretnemu tu nie służy - jest tylko przykładem,
// że sterowniki JDBC mogą posiadać dodatkowe parametry niestandardowe.
public static void main(String[] args) throws SQLException {
Properties props = new Properties();
props.setProperty("user", "kurs");
props.setProperty("password", "abc123");
// props.setProperty("ssl", "true");
props.setProperty("tcpKeepAlive", "true");
String url = "jdbc:postgresql://localhost/hr";
Connection c = DriverManager.getConnection(url, props);
Statement stmt = c.createStatement();
// Statementy można trochę skonfigurować
stmt.setFetchSize(10);
ResultSet rs = stmt.executeQuery("SELECT SUM(salary) FROM employees");
while (rs.next()) {
System.out.print("Wynik: ");
System.out.println(rs.getString(1));
}
rs.close();
stmt.close();
c.close();
}
}
package bazy_danych.postgresql;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
public class P16b_Property_ZPliku {
public static void main(String[] args) {
try {
Properties props = new Properties();
// nazwa pliku jeśli jest w katalogu bieżącym, albo pełna ścieżka do pliku
props.load(new FileInputStream("postgres.properties"));
// props.load(new FileInputStream("C:/jakis_katalog/postgres.properties"));
String url = props.getProperty("url");
Connection c = DriverManager.getConnection(url, props);
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT avg(salary) FROM employees");
if (rs.next()) {
System.out.print("Wynik: ");
System.out.println(rs.getString(1));
}
rs.close();
stmt.close();
c.close();
} catch (SQLException | IOException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
public class P16c_Property_Z_Classpath {
public static void main(String[] args) {
try {
Properties props = new Properties();
// Tutaj odczytany zostanie plik, który znajduje się (wraz z plikami .class) w katalogach / jar-ach
// będących częścią classpath.
// Jeśli podana jest tylko nazwa pliku (albo ścieżka względna), to jako katalog bieżący jest traktowany bieżący pakiet.
// Można też podać ścieżkę bezwzględną np. /gotowe/postgresql/ustawienia_bazy.properties
// to wtedy plik byłby szukany w pakiecie ustawienia
// W projekcie Mavenowym właściwą lokalizacją dla takich plików jest src/main/resources
props.load(P16c_Property_Z_Classpath.class.getResourceAsStream("ustawienia_bazy.properties"));
String url = props.getProperty("url");
Connection c = DriverManager.getConnection(url, props);
Statement stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT avg(salary) FROM employees");
while (rs.next()) {
System.out.print("Wynik: ");
System.out.println(rs.getString(1));
}
rs.close();
stmt.close();
c.close();
} catch (SQLException | IOException e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import javax.sql.RowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
public class P21_RowSet {
public static void main(String[] args) {
try {
//Class.forName("org.postgresql.Driver");
RowSetFactory rsf = RowSetProvider.newFactory();
RowSet rowSet = rsf.createJdbcRowSet();
//RowSet rowSet = rsf.createCachedRowSet(); // też działa
rowSet.setUrl(Ustawienia.URL);
rowSet.setUsername(Ustawienia.USER);
rowSet.setPassword(Ustawienia.PASSWD);
// Moim skromnym zdaniem to przykład złej praktyki "low cohesion" - namieszane za dużo rzeczy w jednej klasie...
String sql = "SELECT first_name, last_name, salary "
+ "FROM employees WHERE salary BETWEEN ? AND ?";
rowSet.setCommand(sql);
rowSet.setInt(1, 8000);
rowSet.setInt(2, 10000);
rowSet.execute();
while (rowSet.next()) {
System.out.printf("%s %s zarabia %s%n", rowSet.getString(1), rowSet.getString(2),
rowSet.getBigDecimal(3));
}
System.out.println();
rowSet.setCommand("SELECT * FROM countries");
rowSet.execute();
while (rowSet.next()) {
System.out.println(rowSet.getString(2));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.math.BigDecimal;
import java.sql.Connection;
import javax.sql.rowset.JdbcRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
import javax.swing.JOptionPane;
/* JdbcRowSet jest "connected".
* 1) Zadawanie wielu zapytań w jednej sesji będzie bardziej wydajne przy użyciu JdbcRowSet niż CachedRowSet,
* bo Jdbc pozostaje połączony, a Cached musi się łączyć za każdym razem.
* 2) Posiada metody do zarządzania transakcjami (commit/rollback/savepoint).
* 3) Umożliwia aktualizację danych poprzez wynik.
*/
public class P22_JdbcRowSet {
public static void main(String[] args) {
// final String JOB = "IT_PROG";
// final BigDecimal ZMIANA = new BigDecimal("1.00");
final String JOB = JOptionPane.showInputDialog("Komu zmienić? (np. IT_PROG)");
final BigDecimal ZMIANA = new BigDecimal(JOptionPane.showInputDialog("O ile zmienić?"));
try {
RowSetFactory rsf = RowSetProvider.newFactory();
JdbcRowSet rowSet = rsf.createJdbcRowSet();
rowSet.setUrl(Ustawienia.URL);
rowSet.setUsername(Ustawienia.USER);
rowSet.setPassword(Ustawienia.PASSWD);
rowSet.setAutoCommit(false);
rowSet.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
String sql = "SELECT employee_id, first_name, last_name, salary FROM employees WHERE job_id = ?";
rowSet.setCommand(sql);
rowSet.setString(1, JOB);
rowSet.execute();
while (rowSet.next()) {
BigDecimal pensja = rowSet.getBigDecimal("salary");
System.out.printf("%s %s zarabia %s%n",
rowSet.getString("first_name"), rowSet.getString("last_name"), pensja);
pensja = pensja.add(ZMIANA);
System.out.println(" ale teraz zmieniam mu pensję na " + pensja);
rowSet.updateBigDecimal("salary", pensja);
rowSet.updateRow();
}
System.out.println();
int coRobic = JOptionPane.showConfirmDialog(null, "Czy zakomitować zmiany?");
switch(coRobic) {
case JOptionPane.YES_OPTION:
rowSet.commit();
break;
case JOptionPane.NO_OPTION:
rowSet.rollback();
break;
case JOptionPane.CANCEL_OPTION:
default:
// do nothing
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;
import javax.sql.RowSet;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.FilteredRowSet;
import javax.sql.rowset.Predicate;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
/* CachedRowSet i jego specjalizacje są disconnected.
* To może zmniejszyć wydajność, ale pozwala kopiować dane i pracować z nimi w oderwaniu od bazy.
*
* FilteredRowSet pozwala nakładać filtry na odczytywane dane.
*/
public class P23_CachedRowSet {
private Connection c;
private RowSetFactory rsf;
P23_CachedRowSet() throws SQLException {
rsf = RowSetProvider.newFactory();
c = DriverManager.getConnection(Ustawienia.URL, Ustawienia.USER, Ustawienia.PASSWD);
}
private void populujWynikiZapytania(String tabela, CachedRowSet cachedRowSet) throws SQLException {
final String sql = "SELECT * FROM " + tabela;
try(PreparedStatement stmt = c.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
cachedRowSet.populate(rs);
// rs można zamknąć
}
}
private void run() throws SQLException {
FilteredRowSet employees = rsf.createFilteredRowSet();
populujWynikiZapytania("employees", employees);
CachedRowSet jobs = rsf.createCachedRowSet();
populujWynikiZapytania("jobs", jobs);
while(jobs.next()) {
String jobId = jobs.getString("job_id");
String jobTitle = jobs.getString("job_title");
System.out.printf("\nPracownicy ze stanowiska %s (%s):\n", jobTitle, jobId);
employees.setFilter(new PredykatJobowy(jobId));
employees.beforeFirst();
while(employees.next()) {
String firstName = employees.getString("first_name");
String lastName = employees.getString("last_name");
System.out.printf(" * %s %s\n", firstName, lastName);
}
}
}
public static void main(String[] args) {
try {
P23_CachedRowSet p13 = new P23_CachedRowSet();
p13.run();
System.out.println("Koniec");
} catch (Exception e) {
e.printStackTrace();
}
}
private static class PredykatJobowy implements Predicate {
private String jobId;
public PredykatJobowy(String jobId) {
this.jobId = jobId;
}
public boolean evaluate(RowSet rs) {
try {
String actualJobId = rs.getString("job_id");
return Objects.equals(jobId, actualJobId);
} catch (SQLException e) {
return false;
}
}
public boolean evaluate(Object value, int column) throws SQLException {
return true;
}
public boolean evaluate(Object value, String columnName) throws SQLException {
return true;
}
}
}
package bazy_danych.postgresql;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.Writer;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
import javax.sql.rowset.WebRowSet;
/* WebRowSet pozwala wyeksportować dane do formatu XML
*/
public class P24_WebRowSet {
public static void main(String[] args) {
try {
System.out.println("Start");
RowSetFactory rsf = RowSetProvider.newFactory();
WebRowSet rowSet = rsf.createWebRowSet();
rowSet.setUrl(Ustawienia.URL);
rowSet.setUsername(Ustawienia.USER);
rowSet.setPassword(Ustawienia.PASSWD);
String sql = "SELECT * FROM employees LEFT JOIN jobs USING(job_id) LEFT JOIN departments USING (department_id) LEFT JOIN locations USING (location_id) LEFT JOIN countries USING (country_id) ORDER BY employee_id";
rowSet.setCommand(sql);
System.out.println("Zadaję zapytanie");
rowSet.execute();
System.out.println("Eksportuję XML");
try(Writer out = new BufferedWriter(new FileWriter("employees.xml"))) {
rowSet.writeXml(out);
}
System.out.println("Gotowe");
} catch (Exception e) {
e.printStackTrace();
}
}
}
package bazy_danych.postgresql;
public class Ustawienia {
public static final String HOST = "localhost";
public static final String PASSWD = "abc123";
public static final String BAZA = "hr";
public static final String URL = "jdbc:postgresql://" + HOST + "/" + BAZA;
public static final String USER = "kurs";
}
url=jdbc:postgresql://localhost/hr
user=kurs
password=abc123
tcpKeepAlive=true
package bazy_danych.sqlite;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
public class P01_Polaczenie {
public static void main(String[] args) {
// JDBC
try {
Connection connection = DriverManager.getConnection(
"jdbc:sqlite:hr.db");
System.out.println("Nawiązano połączenie " + connection);
System.out.println("Klasa: " + connection.getClass().getName());
DatabaseMetaData metaData = connection.getMetaData();
System.out.println(metaData.getDatabaseProductName());
System.out.println(metaData.getDatabaseMajorVersion() + " " + metaData.getDatabaseMinorVersion());
// da się też odczytać listę wszystkich tabel, informacje o tabelach...
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.sqlite;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P02_Odczyt {
public static void main(String[] args) {
try {
Connection c = DriverManager.getConnection("jdbc:sqlite:hr.db");
PreparedStatement stmt = c.prepareStatement("SELECT * FROM employees");
ResultSet rs = stmt.executeQuery();
while(rs.next()) {
// można odczytać kolumny wg numeru - numeracja od 1
String imie = rs.getString(2);
// można też używać nazwy kolumny
String nazwisko = rs.getString("last_name");
BigDecimal pensja = rs.getBigDecimal("salary");
System.out.println(imie + " " + nazwisko + " zarabia " + pensja);
}
rs.close();
stmt.close();
c.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.sqlite;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class P03_Odczyt {
public static void main(String[] args) {
final String sql = "SELECT * FROM employees ORDER BY employee_id";
try(Connection c = DriverManager.getConnection("jdbc:sqlite:hr.db");
PreparedStatement stmt = c.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
// można odczytać kolumny wg numeru - numeracja od 1
String imie = rs.getString(2);
// można też używać nazwy kolumny
String nazwisko = rs.getString("last_name");
BigDecimal pensja = rs.getBigDecimal("salary");
String data = rs.getString("hire_date");
int id = rs.getInt("employee_id");
System.out.printf("%-15s %-15s (%3d) - zatr. %s, pensja %8s\n",
imie, nazwisko, id, data, pensja);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.sqlite;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JOptionPane;
public class P04_Parametry {
public static void main(String[] args) {
String szukani = JOptionPane.showInputDialog("Podaj kod stanowiska");
szukani = szukani.toUpperCase();
// Przykład SQL injection, które zadziałałoby w wersji ze sklejaniem stringów:
// a'; DROP TABLE job_history; SELECT 'ala
// final String sql = "SELECT * FROM employees WHERE job_id = '" + szukani + "'";
// Właściwe podejście: użyć znaków zapytania i metod PreparedStatement.setXXX aby ustawić wartość parametru.
final String sql = "SELECT * FROM employees WHERE job_id = ?";
try(Connection c = DriverManager.getConnection("jdbc:sqlite:hr.db");
PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setString(1, szukani);
try(ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
// można odczytać kolumny wg numeru - numeracja od 1
String imie = rs.getString(2);
// można też używać nazwy kolumny
String nazwisko = rs.getString("last_name");
BigDecimal pensja = rs.getBigDecimal("salary");
String data = rs.getString("hire_date");
int id = rs.getInt("employee_id");
String job = rs.getString("job_id");
System.out.printf("%-15s %-15s (%3d) - zatr. %s, pensja %8s, %s\n",
imie, nazwisko, id, data, pensja, job);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.sqlite;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JOptionPane;
public class P05_DanePracownika {
public static void main(String[] args) {
String s = JOptionPane.showInputDialog("Podaj id pracownika");
int id = Integer.parseInt(s);
// program ma:
// połączyć się z bazą,
// zadać zapytanie (z JOIN i WHERE)
// i wypisać dane tego pracownika:
// first_name, last_name, department_name, street_address, city
// (z tabel employees, departments, locations)
final String sql = "SELECT first_name, last_name, department_name, street_address, city " +
"FROM employees" +
" LEFT JOIN departments USING(department_id)" +
" LEFT JOIN locations USING(location_id)" +
"WHERE employee_id = ?";
try(Connection c = DriverManager.getConnection("jdbc:sqlite:hr.db");
PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setInt(1, id);
try(ResultSet rs = stmt.executeQuery()) {
if(rs.next()) {
System.out.printf("%s %s %s %s %s\n",
rs.getString(1),
rs.getString(2),
rs.getString(3),
rs.getString(4),
rs.getString(5));
} else {
System.out.println("Nie znaleziono takiego pracownika");
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package bazy_danych.sqlite;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class P06_Podwyzka {
public static void main(String[] args) {
String job = "IT_PROG";
int zmiana = 250;
final String sql = "UPDATE employees SET salary = salary + ? WHERE job_id = ?";
try(Connection c = DriverManager.getConnection("jdbc:sqlite:hr.db");
PreparedStatement stmt = c.prepareStatement(sql)) {
stmt.setInt(1, zmiana);
stmt.setString(2, job);
// Także dla poleceń jak INSERT, DELETE czy ALTER TABLE użylibyśmy executeUpdate
int ile = stmt.executeUpdate();
System.out.println("Zmodyfikowano " + ile + " rekordów.");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.inne_bazy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/* Łączenie z bazą Oracle wymaga:
* - sterownika Oracle JDBC (OJDBC)
* - wpisania odpowiedniego URL-a, poniżej przykład, który zadziałał dla Oracle 11 eXpress Edition
*/
public class Oracle {
public static void main(String[] args) {
final String url = "jdbc:oracle:thin:@//10.0.15.13:1521/xe";
try(Connection con = DriverManager.getConnection(url, "HR", "abc123")) {
try(Statement st = con.createStatement()) {
final String sql = "SELECT * FROM countries";
try(ResultSet rs = st.executeQuery(sql)) {
while(rs.next()) {
System.out.print(rs.getString(1));
System.out.print(" ");
System.out.println(rs.getString("country_name"));
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package gotowe.inne_bazy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SQLServer {
public static void main(String[] args) {
try (Connection cn = DriverManager.getConnection(
"jdbc:sqlserver://localhost:1433;database=HR;user=KURS;password=abc123");
PreparedStatement stmt = cn.prepareStatement("SELECT * FROM employees");
ResultSet rs = stmt.executeQuery()) {
while(rs.next()) {
int a = rs.getInt(1);
String b = rs.getString(2);
String c = rs.getString(3);
System.out.println(a + " " + b + " " + c);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment