Advanced SQL¶
约 1526 个字 172 行代码 4 张图片 预计阅读时间 7 分钟
Outline:
- Accessing SQL From a Programming Language
- Functions and Procedures
- Triggers
- Recursive Queries
- Advanced Aggregation Features
Accessing SQL From a Programming Language¶
通常有两种方式来通过编程语言访问数据库:
- API(Application Programming Interface, 应用程序接口) -- 通过函数调用来访问数据库
- Embedded SQL -- 在编程语言中嵌入SQL语句
- The SQL statements are translated at compile time into finction calls
- At runtime, these function calls connect to the database using an API that provides dynamic SQL facilities
- 在编译的时候,这些 SQL 语句会被预编译,然后在运行时,这些预编译的 SQL 语句会被转换成函数调用,然后通过 API 来连接数据库
JDBC and ODBC
- API for a program to interact with a database server
- ODBC(Open Database Connectivity) works with C, C++, C#
- JDBC(Java Database Connectivity) works with Java
- Embedded SQL in C
- SQLJ - embedded SQL in Java
- JPA(Java Persistence API) - Java ORM(Object-Relational Mapping) API
JDBC¶
JDBC supports a variety of features for qureying and updating data, and for retrieving query results.
JDBC also supports metadata retrieval, which allows a program to determine the structure of a database and the types of data stored in it.
Model for communication with the database:
- Open a connection
- Create a "statement" object
- Execute queries using the Statement object to send qureies and fetch results
- Exception mechanism to handle errors
Try - catch 语句
我们把可能会出现异常的代码放在 try 代码块中,如果出现异常了,就会跳到 catch 代码块中,然后执行 catch 代码块中的代码来处理异常。
Update to database:
Java | |
---|---|
Execute query and fetch and print results:
Java | |
---|---|
我们看到,JDBC 中一个不方便的点在于,如果我们想获得每一列的数据,我们需要使用 rset.getString(dept_name)
或者 rset.getFloat(2)
这样的方式来获取数据,但是万一我们不知道这个数据的类型的话,就不能这么用了。
所以我们可以用 metadata
来获取数据的类型:
Java | |
---|---|
这段程序可以输出每一列的名字和类型。
Prepared Statements¶
我们可以用占位符来代替具体的值,然后在执行的时候再传入具体的值,可以视为将 SQL 语句模版化,还可以防止 SQL 注入攻击。
Java | |
---|---|
SQL 注入攻击
从用户端接收数据时,一定要用 Prepared Statements。“永远相信你的用户非蠢即坏”。
假如我们的查询语句需要用户输入查询的名字,而我们的查询语句是这样的:
SQL | |
---|---|
如果用户输入了 X' or 'Y' = 'Y
,那么这个查询语句就会变成:
SQL | |
---|---|
就永远为真,这样就会泄露所有的数据。
MetaData¶
- ResultSet metadata
Java | |
---|---|
- Database metadata
Transaction Control in JDBC¶
- Can turn off auto-commit mode
conn.setAutoCommit(false)
- Transactions must then be committed or rolled back explicitly
conn.commit()
conn.rollback()
SQLJ¶
SQLJ: embedded SQL in Java
加上 #sql
这个标签,就可以直接在 Java 代码中写 SQL 语句了。
ODBC¶
Each database system supporting ODBC provides a "driver" library that must be linked with the client program.

Example
由于 C 没有 class, 所以所有的功能都是通过函数来实现的。
同一个数据库可能服务于多个对象,使用不同的编程语言,如字符串的结束标志也可能不同,所以需要用 SQL_NTS
来表示字符串的结束。
- Program sends SQL commands to database by using SQLExecDirect
- Result tuples are fetched using SQLFetch()
- SQLBindCol() binds C language variables to attributes of the query result
- When a tuple is fetched, its attribute values are automatically stored in corresponding C variables
- Arguments to SQLBindCol()
- ODBC stmt variable, attribute positionin query result
- The type conversion from SQL to C
- The address of the variable
- For variable-length types like character arrays,
- The maximum length of the variable
- Location to store actual length when a tuple is fetched
- Note: A negative value returned for the length field indicates null value
Example
Main body of program
ODBC Prepared Statements¶
- Prepared Statement
- SQL statement Prepared: compiled at the database
- Can have placeholders: E.g.
insert into account values(?, ?, ?)
- Repeatedly executed with actual values for the placeholders
- To prepare a statement
SQLPrepare()
- To bind parameters
SQLBindParameter(stmt, <parameter#>), ... type information and value omitted for simplicity...);
- To execute the statement
retcode = SQLExecute(stmt);
More ODBC Features¶
- Metadata features
- finding all the relations in the database
- finding the names and types of columns of a query result or a relation in the database
- By default, each SQL statement is treated as a separate transaction that is committed automatically
- Can turn off automatic commit on a connection
SQLSetConnectOption(conn, SQL_AUTOCOMMIT, 0);
- Transactions must then be committed or rolled back explicitly
SQLTransact(conn, SQL COMMIT);
SQLTransact(conn, SQL ROLLBACK);
- Can turn off automatic commit on a connection
Embedded SQL¶
A language to which SQL queries are embedded is referred to as a host language, and the SQL structures permitted in the host language comprise embedded SQL.
如果把 SQL 嵌入到 Java 中,那么 Java 就是 host language.
EXEC SQL
statements is used in the host language to identify embedded SQL requests to the preprocessor.(in java, it is#sql
)
Issues with Embedded SQL:
- Mark the start point and end point of Embedded SQL.
EXEC SQL <statement>
- Communication between database and programming language.
- SQLCA, SQLDA
- Address the mismatching issue between SQL and host lanugage.
- Handle result (set) with cursor
- Mapping of basic data types: SQL: date -> C: char(12)
Example
注意:C语言与 SQL 语言有不匹配的地方,比如 C 语言中没有 date 类型,所以我们需要把 date 类型转换成 char 类型。
Procedural Constructs in SQL¶
- SQL provides a module language
- Permits definition of procedures in SQL, with
if-then-else
statements,for
andwhile
loops, etc.
- Permits definition of procedures in SQL, with
- Stored Procedures
- Can store procedures in the database
- then execute them using the call statement
- permit external applications to operate on the database without knowing about internal details
SQL Functions¶
Define a function that, given the name of a department, returns the count of the number of instructors in that department.
SQL | |
---|---|
然后调用这个函数:
Find the department name and budget of all departments with more that 12 instructors.
函数还能返回一个 table:
Return all accounts owned by a given customer
SQL | |
---|---|
Usage:
SQL | |
---|---|
SQL Procedures¶
可以添加输入in
和输出out
参数。

Procedural Constraints¶
- Compound statement: begin ... end,
- May contain multiple SQL statements between begin and end
- Local variables can be declared within a compound statement
- while and repeat statements:
SQL | |
---|---|
- for loop:
- Permits iteration over all results of a query
SQL | |
---|---|
- if-then-else statement:
SQL | |
---|---|

External Language Functions/Procedures¶
可以使用外部的由其他语言编写的函数和过程。
SQL | |
---|---|
但是这样会出现一个问题,如果外部的程序是病毒,那么就会对数据库造成很大的危害。
所以一般在 sandbox 或容器中运行这些程序。
Triggers¶
- A trigger is a statement that is executed automatically by the system as a side effect of a modification to the database.
- Trigger - ECA rule
- E: Event(insert, delete, update)
- C: Condition
- A: Action
- To design a trigger mechanism, we must:
- Specify the conditions under which the trigger is to be executed.
- Specify the actions to be taken when the trigger executes.
Example
time_slot_id
虽然 time_slot_id
不是 primary key
, 我们仍然可以设计一个触发器来保证 time_slot_id
的引用完整性。

Statement Level Triggers¶
除了 for each row
之外,还有 for each statement
.
前者是对每一行进行操作,后者是对每一条语句进行操作。
Instead of executing a separate action for each affected row, a single action can be executed for all rows affected by a transaction.
- Use
for each statement
instead offor each row
- Use
referencing old table
orreferencing new table
to refer to temporary tables (called transition tables) containing the affected rows. - Can be more effective when dealing with SQL statements that update a large number of rows.
Example