ODBC和JDBC

ODBC

开放数据互联(Open DATABase Connection, ODBC)是微软公司开放的服务结构(Windows Open Services Architecture, WOSA)中有关数据库的一个组成部分。并提供了一套对数据库方位的标准API(Application Programming Interface)这些API独立于不同的DBMS,应用程序可以使用相同的ODBC来访问任何支持ODBC标准的数据库。

void ODBCDemo(){
  RETCODE error;
  HENV env;
  HDBC conn;

  SQLAllocEnv(&env);
  SQLAllocConnection(env, &conn);
  SQLConnect(conn, "de.yale.edu", SQL_NTS, "avi", SQL_NTS,
    "passwords", SQL_NTS);
  {
    char deptname[80];
    float salary;
    int lenOut1, lenOut2;
    HSTMT stmt;

    char* sqlquery = "select depy_name, sum(salary)
      from instructor 
      group by dept_name";
    SQLAllocStmt(conn, &stmt);
    error = SQLExecDirect(stmt, sqlquery, SQL_NTS);
    if(error == SQL_SUCCESS){
      SQLBindCol(stmt, 1, SQL_C_CHAR, deptname, 80, &lenOut1);
      SQLBindCol(stmt, 2, SQL_C_FLOAT, &salary, 0, &lenOut2);
      while (SQLFetch(stmt) == SQL_SUCCESS){
        printf("%s %g\n", deptname, salary);
      }
    }
    SQLFreeStmt(stmt, SQL_DROP);
    SQLDisconnect(conn);
    SQLFreeConnect(conn);
    SQLFreeEnv(env);
  }
}

SQL的储存过程与函数

SQL中可以创建储存过程和函数,把他们储存在数据库服务器中,并在SQL语句中调用

储存过程

储存过程(Stored Procedure)是为了完成特定的功能而汇聚成的一组语句,对该组语句命名,编译和优化后储存在数据库服务器中。用户可以指定在储存过程的名字并给出相应的参数来执行它。

SQL/PSM

创建储存过程和函数可以指定所使用的一种程序设计语言。

SQL/PSMSQL标准的一部分,它指出了如何编写SQL持久储存模块,其中包括创建储存过程和函数的语句。

条件控制语句

IF <condition> THEN <{expressions}>
  ElSEIF <condition> THEN <{expressions}>
  ...
  ElSEIF <condition> THEN <{expressions}>
  ELSE <condition>
END IF

循环控制语句

WHILE <condition> DO
  <{expressions}>
END WHILE

REPEAT
  <{expression}>
  UNTIL <condition>
END REPEAT

FOR <repeat_name> AS <role_name> CURSOR FOR <search> DO
  <{expression}>
END FOR

创建、执行和删除储存过程和函数


-- 创建储存过程
CREATE PROCEDURE <procedure_name> ([{arguments}]) [<{Partial_declaration}>] <procedure_body>;

-- 创建函数体
CREATE FUNCTION <function_name> (<{arguments}>) RETURNS <return_type> [<{Partial_declaration}>] <function_body>;

-- 指定通用语言
CREATE PROCEDURE <procedure_name> (<{arguments}>) LANGUAGE <programming_language> EXTERNAL NAME <file_path>;

-- 执行储存过程和函数
CALL <procedure_name | function_name> ([<arguments>)

-- 删除储存过程或函数
DROP PROCEDURE <procedure_name>;
DROP FUNCTION <function_name>;

实例

CREATE PROCEDURE TRANSFER (inaccount INT, outaccount INT, amount FLOAT);
  DECLARE totaldeposit FLOAT;   -- 申明变量
  SELECT total INFO totaldeposit FLOAT;
  SELECT total INTO totaldeposit FROM ACCOUNT
    WHERE ACCOUNTNUM = outaccount;  -- 检查转出余额
  IF otaldeposit IS NULL THEN  -- 账户没有存款,回滚事务
    ROLLBACK;
    RETURN;
  ELSEIF otaldeposit <amount THEN -- 余额不足,回滚事务,并返回
    ROLLBACK;
    RETURN;
  ELSE --修改转出账户,减去转出额
    UPDATE ACCOUNT SET total = total - amount
      WHERE ACCOUNTNUM = outaccount;
    UPDATE ACCOUNT SET tatal = total + amount
      WHERE ACCOUNTNUM = inaccountl
    COMMIT; -- 转账完成,提交转账事务
  ENDIF;

SQL触发器

概述:触发器是用户定义在表上的一类特殊储存过程,触发器的执行是通过事件来出发执行的。

创建触发器

SQL使用CREATE TRIGGER语句创建触发器

CREATE TRIGGER trigger_name
  | BEFORE | AFTER | trigger_event ON table_name
  FOR EACH | ROW | STATEMENT | [WHEN <condition>]
  <trigger_action>

其中trigger_event可取值:INSERT, DELETE, UPDATE
trigger_action一般用BEGIN ... END括起来,或者AS引导

激活触发器

触发器是trigger_event发生时激活的,一个触发器只能作用于一张表,一个表上可以创建多个触发器,分别针对INSERT, UPDATEBEFORE, AFTER的任意组合。

删除触发器

DROP TRIGGER <trigger_name>

触发器示例

下面是一个简易的周六或周日,尝试修改表时触发报错

CREATE TRIGGER tri_name
  BEFORE INSERT OR DELETE OR UPDATE ON table_name
DECLARE
  weekend_error EXCEPTION;
BEGIN 
  IF TO_CHAR(SysDate, 'DY') = 'SAT' OR
    TO_CHAR(SysDAte, 'DY') = 'SUM'
  THEN RAISE weekend_error;
  end if
EXCEPTION 
  WHEN weekend_error THEN
    RAISE_APPLICATION_ERROR(-20001, 'error!');
  RETURN;
END;

嵌入式SQL