일반 목적의 프로그래밍 언어(C++/Java 등)에서 SQL을 함께 써야할 때가 있음
public static void JDBCexample(String dbid, String userid,
String passwd)
{
try {
Connection conn = DriverManager.getConnection(
"jdbc:postgresql://localhost/db_name",
userid, passwd);
Statement stmt = conn.createStatement();
/*… Do Actual Work … shown in below */
stmt.close();
conn.close();
}
catch (SQLException sqle) {
System.out.println("SQLException : " + sqle);
}
}
try {
stmt.executeUpdate(
"insert into instructor \\
values ( '77987', 'Kim', 'Physics', 98000)");
} catch (SQLException sqle) {
System.out.println("Could not insert tuple." + sqle);
}
ResultSet rset = stmt.executeQuery(
"select dept_name, avg (salary)
from instructor
group by dept_name");
while (rset.next()) {
System.out.println(rset.getString("dept_name") + " " + rset.getFloat(2));
}
stmt.executeUpdate(“SELECT dept_name FROM students " +
“WHERE name= ’ " + name + " ’) " );
Robert’; DROP TABLE students; --를 입력한다면SELECT dept_name FROM students WHERE name= 'Robert';
DROP TABLE students;
이를 막기 위해 PreparedStatement를 사용할 수 있음. 이안에서는 모든 따옴표가 escape됨.
PreparedStatement pStmt = conn.prepareStatement("insert into instructor values(?,?,?,?)");
pStmt.setString(1, "88877"); /*parameter index, value*/
pStmt.setString(2, "Perry");
pStmt.setString(3, "Finance");
pStmt.setInt(4, 125000);
pStmt.executeUpdate();
pStmt.setString(1, "88878");
pStmt.executeUpdate();
Resultset의 메타데이터
ResultSet rset;
...
ResultSetMetaData rsmd = rset.getMetaData();
for(int i = 1; i <= rsmd.getColumnCount(); i++)
{
System.out.println(rsmd.getColumnName(i));
System.out.println(rsmd.getColumnTypeName(i));
}
DatabaseMetaData
DatabaseMetaData dbmd = conn.getMetaData();
ResultSet rset = dbmd.getColumns(null, "univdb",
"department", "%");
// Returns: One row for each column;
// row has a number of attributes, e.g., COLUMN_NAME,
// TYPE_NAME, etc
while(rset.next()) {
System.out.println(rset.getString("COLUMN_NAME"),
rset.getString("TYPE_NAME");
}
conn.setAutoCommit(false);conn.commit(); // or
conn.rollback();CREATE [OR REPLACE] FUNCTION function_name (arguments)
RETURNS return_datatype AS $$
DECLARE
declaration;
[...]
BEGIN
< function_body >
[...]
RETURN { variable_name | value }
END;
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION total_students()
RETURNS integer AS $$
declare
total integer;
BEGIN
SELECT count(*) into total FROM STUDENT;
RETURN total;
END;
$$
LANGUAGE plpgsql;
IF <condition> then
<statements>
ELSEIF <condition> then
<statements>
ELSE
<statements>
END IF
CASE <expression>
WHEN <value> then
<statements>
WHEN <value> then
<statements>
…
ELSE
<statements>
END CASE;
조건문들로도 만들 수 있다.
CASE
WHEN <condition> then
<statements>
WHEN <condition> then
<statements>
…
ELSE
<statements>
END CASE;
예시:
DO $$
DECLARE
letter VARCHAR(10);
grade_value VARCHAR(10);
BEGIN
FOR letter IN SELECT grade FROM takes
LOOP
grade_value := CASE letter
WHEN 'A' THEN '4'
WHEN 'B' THEN '3'
WHEN 'C' THEN '2’
ELSE 'other'
END;
RAISE NOTICE 'Grade: %, Value: %', letter, grade_value;
END LOOP;
END $$;
LOOP
-- some computations
IF count > 0 THEN
EXIT; -- exit loop
END IF;
END LOOP;
WHILE var1 > 0 AND var2 > 0 LOOP
-- some computations here
END LOOP;
DO $$
DECLARE i INT;
BEGIN
FOR i IN 1..10 LOOP
RAISE NOTICE ‘i = %’, i;
END LOOP;
END $$;
DO $$
DECLARE s RECORD;
BEGIN
FOR s IN
SELECT id, name FROM student
LOOP
RAISE NOTICE 'id= %, name = %', s.id, s.name;
END LOOP;
END $$;
CREATE FUNCTION scan_rows(int[])
RETURNS void AS $$
DECLARE
x int[];
BEGIN
FOREACH x SLICE 1 IN ARRAY $1
LOOP
RAISE NOTICE 'row = %', x;
END LOOP;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger-name
trigger-time trigger-event ON table-name
FOR EACH ROW
trigger-action;
trigger-time {BEFORE, AFTER}trigger-event {INSERT, DELETE, UPDATE}CREATE OR REPLACE FUNCTION update_budget()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.dept_name IS NOT NULL THEN
UPDATE department
SET budget = budget + NEW.salary
WHERE dept_name = NEW.dept_name;
END IF;
RETURN NEW; -- new refers to the new row inserted
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_budget
AFTER INSERT ON instructor
FOR EACH ROW
EXECUTE PROCEDURE update_budget();