首页 > 代码库 > java在sybase上创建特定触发器

java在sybase上创建特定触发器


本文是小小的总结一下本人开发时要在sybase数据库上创建特定的触发器

创建的触发器完成的功能如下

在数据库中指定的表上创建插入,更新,删除触发器,当指定的表发生插入、更新或者删除操作时,将触发触发器相应的动作,触发器的作用就是,将发生上述操作的表的表名、主键名、对应的主键值、相应的操作存到另一张记录表中。本总结中除了创建该类型触发器外还包括删除触发器,删除记录表,判断是否已有记录表。

需要导入的架包:activejdbc.jar,jconn3.jar:

import java.util.List;import java.util.Map;import org.javalite.activejdbc.Base;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * 模板类 * @author ywnwa * */public abstract class AbstractTriggerManager implements TriggerManager {    protected static final String TRIGGER_EVENT_TABLE_NAME = "TRIGGER_EVENTS";    private final Logger          logger                   = LoggerFactory                                                                   .getLogger(getClass());    private final String          user;    private final String          password;    public AbstractTriggerManager(String user, String password) {        this.user = user;        this.password = password;    }    public void openDatabase() {        Base.open(getDriverClass(), getUrl(), this.user, this.password);        logger.debug("open database sucessfuly!");    }    public void closeDatabase() {        Base.close();        logger.debug("close database sucessfuly!");    }    @SuppressWarnings("rawtypes")    public boolean hasEventTable() {        // NOTE (Tan Bingjian)        // the values of table_name must be given in capital        List<Map> result = Base.findAll(getSelectTriggerEventTableSql());        return !result.isEmpty();    }    public void createEventTable() {        if (!hasEventTable()) {            logger.debug("TRIGGER_EVENTS is not exist! It will be created .");            Base.exec(getCreateEventTableSql());            logger.debug("TRIGGER_EVENTS create successfuly!");        }        logger.debug("TRIGGER_EVENTS is get ready !");    }    public void dropEventTable() {        if (hasEventTable()) {            Base.exec(getDropEventTableSql());            logger.debug("TRIGGER_EVENTS drop successfuly!");        }    }    @Override    public void create(String name) {        // trigger for insert        Base.exec(sqlForTrigger(name, "insert"));        // trigger for delete        Base.exec(sqlForTrigger(name, "delete"));        // trigger for update        Base.exec(sqlForTrigger(name, "update"));        logger.debug("The triggers on table " + name                + " create successfuly ! !");    }    @Override    public void remove(String tableName) {        String[] actions = getActionsType();// { "INSERT", "UPDATE", "DELETE" };        for (String i : actions) {            String triggerName = String.format("TR_%s_%s", tableName, i);            logger.debug("look for " + triggerName + " on table :" + tableName);            if (triggerExists(tableName, triggerName)) {                dropTrigger(triggerName);                logger.debug("the trigger has been deleted !");            } else {                logger.debug("the trigger no existe !");            }        }    }    @Override    public void removeAll() {        List<String> tableNames = getAllTables();        for (String name : tableNames) {            remove(name);        }    }    // @Override    public void removeAll(boolean removeEventTable) {        removeAll();        if (removeEventTable && hasEventTable()) {            dropEventTable();        }    }    @SuppressWarnings("rawtypes")    public boolean triggerExists(String tableName, String triggerName) {        List<Map> result = Base.findAll(getSelectTriggersSql(tableName,                triggerName));        return !result.isEmpty();    }    protected void dropTrigger(String triggerName) {        Base.exec(getDropTriggerSql(triggerName));    }    protected String getEventTableName() {        return TRIGGER_EVENT_TABLE_NAME;    }    protected abstract List<String> getAllTables();    protected abstract String getDriverClass();    protected abstract String getUrl();    protected abstract String getSelectTriggerEventTableSql();    protected abstract String sqlForTrigger(String tableName, String opType);    protected abstract String getSelectTriggersSql(String tableName,            String triggerName);    protected abstract String getDropTriggerSql(String triggerName);    protected abstract String getCreateEventTableSql();    protected abstract String getDropEventTableSql();    protected abstract String[] getActionsType();}

这个只是模板类不做过多介绍,下面是具体的实现类:

import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import org.javalite.activejdbc.Base;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class SyBaseTriggerManager extends AbstractTriggerManager {    private final Logger        logger                         = LoggerFactory                                                                       .getLogger(getClass());    private static final String URL_TEMPLATE                   = "jdbc:sybase:Tds:%s:%s/%s";    private static final String SELECT_TABLES_SQL_TEMPLATE     = "select name from sysobjects where type=‘U‘";    private static final String DRIVER_CLASS                   = "com.sybase.jdbc3.jdbc.SybDriver";    private static final String TRIGGER_EVENT_TABLE_NAME       = "TRIGGER_EVENTS";    private static final String SELECT_TRIGGER_EVENT_TABLE_SQL = "select name from sysobjects where name=‘"                                                                       + TRIGGER_EVENT_TABLE_NAME                                                                       + "‘";    private static final String CREATE_TRIGGER_EVENT_TABLE_SQL = "CREATE TABLE "                                                                       + TRIGGER_EVENT_TABLE_NAME                                                                       + "(TRIGGER_EVENTS_ID INT IDENTITY NOT NULL PRIMARY KEY ,"                                                                       + " dbName varchar(30),"                                                                       + " tableName varchar(30),"                                                                       + " pkNames    varchar(2000),"                                                                       + " pkValues varchar(2000),"                                                                       + " action     varchar(20))";    private static final String SELECT_PK_NAMES_SQL_TEMPLATE   = "select columnname from (SELECT  object_name(id) tabname,  index_col( object_name(id) ,indid,1) columnname  FROM sysindexes  WHERE status & 2048=2048 "                                                                       + "union "                                                                       + "SELECT  object_name(id),  index_col( object_name(id) ,indid,2)  FROM sysindexes    WHERE status & 2048=2048 "                                                                       + "union "                                                                       + "SELECT  object_name(id),  index_col( object_name(id) ,indid,3)  FROM sysindexes    WHERE status & 2048=2048 "                                                                       + "union "                                                                       + "SELECT  object_name(id),  index_col( object_name(id) ,indid,4)  FROM sysindexes    WHERE status & 2048=2048 "                                                                       + "union "                                                                       + "SELECT  object_name(id),  index_col( object_name(id) ,indid,5)  FROM sysindexes    WHERE status & 2048=2048 "                                                                       + "union "                                                                       + "SELECT  object_name(id),  index_col( object_name(id) ,indid,6)  FROM sysindexes    WHERE status & 2048=2048 "                                                                       + "union "                                                                       + "SELECT  object_name(id),  index_col( object_name(id) ,indid,7)  FROM sysindexes    WHERE status & 2048=2048 "                                                                       + "union "                                                                       + "SELECT  object_name(id),  index_col( object_name(id) ,indid,8)  FROM sysindexes    WHERE status & 2048=2048 "                                                                       + "union "                                                                       + "SELECT  object_name(id),  index_col( object_name(id) ,indid,9)  FROM sysindexes    WHERE status & 2048=2048 "                                                                       + "union "                                                                       + "SELECT  object_name(id),  index_col( object_name(id) ,indid,10)  FROM sysindexes    WHERE status & 2048=2048 "                                                                       + ")pk where  columnname is not null and tabname=‘%s‘";    private static final String SELECT_TRIGGERS_SQL_TEMPLATE   = "select name from sysobjects  where  type = ‘TR‘and name=‘%s‘";    private static final String DROP_TRIGGER_SQL_TEMPLATE      = "drop trigger %s";    private static final String DROP_TRIGGER_EVENT_TABLE_SQL   = "drop table "                                                                       + TRIGGER_EVENT_TABLE_NAME;    private final String        url;    private final String        host;    private final int           port;    private final String        db;    private final String        user;    private final String        password;    public SyBaseTriggerManager(String host, int port, String db, String user,            String password) {        super(user, password);        this.db = db;        this.user = user;        this.port = port;        this.host = host;        this.url = String.format(URL_TEMPLATE, host, port, db);        this.password = password;    }    @SuppressWarnings("rawtypes")    @Override    protected List<String> getAllTables() {        List<Map> result = Base.findAll(SELECT_TABLES_SQL_TEMPLATE);        List<String> names = new ArrayList<String>();        for (Map row : result) {            names.add(row.get("name").toString());        }        return names;    }    protected String getHost() {        return host;    }    protected int getPort() {        return port;    }    protected String getDb() {        return db;    }    protected String getUser() {        return user;    }    protected String getPassword() {        return password;    }    @Override    protected String getDriverClass() {        return DRIVER_CLASS;    }    @Override    protected String getUrl() {        return url;    }    @Override    protected String getSelectTriggerEventTableSql() {        return SELECT_TRIGGER_EVENT_TABLE_SQL;    }    @Override    protected String sqlForTrigger(String tableName, String opType) {        String actionTo;        String[] pkeys = getPks(tableName);        String tigger;        String va = "";        String declare = "";        String values = "";        String pk = "";        if (opType.equals("insert") || opType.equals("update")) {            actionTo = "inserted ";        } else {            actionTo = "deleted ";        }        for (int i = 0; i < pkeys.length; i++) {            pk += pkeys[i] + ",";            va += "@" + pkeys[i] + "+" + "‘,‘" + "+";            declare += "@" + pkeys[i] + " varchar(20)" + ",";            values += "select " + "@" + pkeys[i] + "=convert(char(200),"                    + pkeys[i] + ")" + " from " + actionTo;        }        declare = declare.substring(0, declare.lastIndexOf(","));        va = va.substring(0, va.lastIndexOf("+"));        tigger = "create trigger TR_%s_%s  on %s"                + " for %s as  declare %s  begin" + " %s  insert into  %s"                + "(dbName,tableName,pkNames,pkValues,action)"                + "values(‘%s‘,‘%s‘,‘%s‘,%s,‘%s‘)  end";        return String.format(tigger, tableName, opType, tableName, opType,                declare, values, TRIGGER_EVENT_TABLE_NAME, db, tableName, pk,                va, opType);    }    @Override    protected String getSelectTriggersSql(String tableName, String triggerName) {        return String.format(SELECT_TRIGGERS_SQL_TEMPLATE, triggerName);    }    @Override    protected String getDropTriggerSql(String triggerName) {        return String.format(DROP_TRIGGER_SQL_TEMPLATE, triggerName);    }    @Override    protected String getCreateEventTableSql() {        return CREATE_TRIGGER_EVENT_TABLE_SQL;    }    @Override    protected String getDropEventTableSql() {        return DROP_TRIGGER_EVENT_TABLE_SQL;    }    @SuppressWarnings({ "rawtypes" })    public String[] getPks(String tableName) {        ArrayList<Map> list3 = new ArrayList<Map>();        list3 = (ArrayList<Map>) Base.findAll(String.format(                SELECT_PK_NAMES_SQL_TEMPLATE, tableName));        String[] pkNames = new String[list3.size()];        for (int i = 0; i < list3.size(); i++) {            Map map = list3.get(i);            Set set = map.keySet();            Iterator it = set.iterator();            while (it.hasNext()) {                pkNames[i] = (String) map.get(it.next());                System.out.println(pkNames[i]);            }        }        return pkNames;    }    public void create(String tableName) {        String[] actions = { "insert", "update", "delete" };        for (String i : actions) {            String triggerName = String.format("TR_%s_%s", tableName, i);            if (triggerExists(tableName, triggerName)) {                dropTrigger(triggerName);            }            Base.exec(sqlForTrigger(tableName, i));        }        logger.debug("The triggers on table " + tableName                + " create successfuly ! !");    }    @Override    protected String[] getActionsType() {        String[] actions = { "insert", "update", "delete" };        return actions;    }}

关键语句介绍:

private static final String SELECT_PK_NAMES_SQL_TEMPLATE

获取对应表的主键名语句,即对应表的主键名,不过这条语句有个局限性是最多只能获取表中只有10个主键的表,超过十个的话第十一个主键将不再获取。如果大家有更加自由的方法欢迎交流。

 protected String sqlForTrigger(String tableName, String opType)

该方法返回创建触发器语句

创建触发器语句:return返回的是完整的语句

 tigger = "create trigger TR_%s_%s  on %s"                + " for %s as  declare %s  begin" + " %s  insert into  %s"                + "(dbName,tableName,pkNames,pkValues,action)"                + "values(‘%s‘,‘%s‘,‘%s‘,%s,‘%s‘)  end";        return String.format(tigger, tableName, opType, tableName, opType,                declare, values, TRIGGER_EVENT_TABLE_NAME, db, tableName, pk,                va, opType);

对了,sybase数据库对大小写敏感,还有就是sybase似乎不支持中文创表,和记录中有中午,也许是我还不够了解,懂的朋友欢迎指导

最后,这是第一次写技术博客,就大概贴出了代码,还有很多不足的地方,请大家多多指教,欢迎一起探讨共同进步。

 

java在sybase上创建特定触发器