本文是小小的总结一下本人开发时要在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似乎不支持中文创表,和记录中有中午,也许是我还不够了解,懂的朋友欢迎指导
最后,这是第一次写技术博客,就大概贴出了代码,还有很多不足的地方,请大家多多指教,欢迎一起探讨共同进步。
时间: 2024-11-03 05:42:44