package jef.database.dialect; import java.sql.Types; import jef.database.ConnectInfo; import jef.database.dialect.ColumnType.AutoIncrement; import jef.database.dialect.handler.LimitHandler; import jef.database.dialect.handler.SQL2000LimitHandler; import jef.database.dialect.handler.SQL2000LimitHandlerSlowImpl; import jef.database.dialect.type.AColumnMapping; import jef.database.dialect.type.ParserFactory; import jef.database.jdbc.statement.UnionJudgement; import jef.database.meta.DbProperty; import jef.database.meta.Feature; import jef.database.query.Func; import jef.database.query.Scientific; import jef.database.query.function.EmuDecodeWithCase; import jef.database.query.function.EmuSQLServerTimestamp; import jef.database.query.function.EmuSQLServerTrunc; import jef.database.query.function.EmuTranslateByReplace; import jef.database.query.function.NoArgSQLFunction; import jef.database.query.function.StandardSQLFunction; import jef.database.query.function.TemplateFunction; import jef.database.query.function.VarArgsSQLFunction; import jef.database.support.RDBMS; import jef.tools.collection.CollectionUtils; import jef.tools.string.JefStringReader; /** * Dialect for SQL Server 2000 and before.. * * @author jiyi * */ public class SQLServer2000Dialect extends AbstractDialect { public SQLServer2000Dialect() { super(); features = CollectionUtils.identityHashSet(); features.add(Feature.COLUMN_DEF_ALLOW_NULL); features.add(Feature.CONCAT_IS_ADD); features.add(Feature.NOT_SUPPORT_KEYWORD_DEFAULT); features.add(Feature.BATCH_GENERATED_KEY_BY_FUNCTION); features.add(Feature.SUPPORT_COMMENT); // features.add(Feature.NO_BIND_FOR_INSERT); // features.add(Feature.NO_BIND_FOR_SELECT); setProperty(DbProperty.ADD_COLUMN, "ADD"); setProperty(DbProperty.MODIFY_COLUMN, "ALTER COLUMN"); setProperty(DbProperty.DROP_COLUMN, "DROP COLUMN"); setProperty(DbProperty.ADD_CONSTRAINT, "ADD CONSTRAINT"); setProperty(DbProperty.CHECK_SQL, "select 1"); setProperty(DbProperty.GET_IDENTITY_FUNCTION, "SELECT @@IDENTITY"); setProperty(DbProperty.WRAP_FOR_KEYWORD, "[]"); setProperty(DbProperty.DROP_INDEX_TABLE_PATTERN, "%2$s.%1$s"); loadKeywords("sqlserver_keywords.properties"); typeNames.put(Types.BINARY, "binary($l)", 0); typeNames.put(Types.BIT, "tinyint", Types.TINYINT); typeNames.put(Types.BIGINT, "numeric(19,0)", 0); typeNames.put(Types.DOUBLE, "double precision", 0); typeNames.put(Types.DATE, "datetime", Types.TIMESTAMP); typeNames.put(Types.TIME, "datetime", Types.TIMESTAMP); typeNames.put(Types.TIMESTAMP, "datetime", 0); typeNames.put(Types.VARBINARY, "varbinary($l)", 0); typeNames.put(Types.NUMERIC, "numeric($p,$s)", 0); typeNames.put(Types.BLOB, "image", 0); typeNames.put(Types.CLOB, "text", 0); typeNames.put(Types.VARBINARY, "image", 0); typeNames.put(Types.VARBINARY, 8000, "varbinary($l)", 0); typeNames.put(Types.LONGVARBINARY, "image", 0); typeNames.put(Types.LONGVARCHAR, "text", Types.CLOB); typeNames.put(Types.BOOLEAN, "bit", Types.BIT); registerNative(Func.coalesce); registerAlias(Func.nvl, "coalesce"); registerNative(Scientific.cot); registerNative(Scientific.exp); registerNative(Scientific.ln, "log"); registerNative(Scientific.radians); registerNative(Scientific.degrees); registerNative(new StandardSQLFunction("ceiling")); registerAlias(Func.ceil, "ceiling"); registerNative(Func.floor); registerNative(Func.round); registerNative(Func.nullif); registerNative(Func.replace); registerNative(Func.substring); registerNative(Func.ltrim); registerNative(Func.rtrim); registerNative(Func.lower); registerNative(Func.upper); registerNative(Func.cast); registerNative(Func.replace); registerAlias("substr", "substring"); registerAlias("lcase", "lower"); registerAlias("ucase", "upper"); registerCompatible(Func.translate, new EmuTranslateByReplace()); registerNative(new NoArgSQLFunction("@@datefirst", false)); registerNative(new NoArgSQLFunction("@@options", false)); registerNative(new NoArgSQLFunction("@@dbts", false)); registerNative(new NoArgSQLFunction("@@remserver", false)); registerNative(new NoArgSQLFunction("@@langid", false)); registerNative(new NoArgSQLFunction("@@servername", false)); registerNative(new NoArgSQLFunction("@@language", false)); registerNative(new NoArgSQLFunction("@@options", false)); registerNative(new NoArgSQLFunction("@@servicename", false)); registerNative(new NoArgSQLFunction("@@lock_timeout", false)); registerNative(new NoArgSQLFunction("@@spid", false)); registerNative(new NoArgSQLFunction("@@textsize", false)); registerNative(new NoArgSQLFunction("@@max_precision", false)); registerNative(new NoArgSQLFunction("@@max_connections", false)); registerNative(new NoArgSQLFunction("@@version", false)); registerNative(new NoArgSQLFunction("@@nestlevel", false)); registerNative(new StandardSQLFunction("char")); registerNative(new StandardSQLFunction("ascii")); registerNative(new StandardSQLFunction("space")); registerNative(new StandardSQLFunction("patindex")); registerNative(new StandardSQLFunction("charindex")); registerNative(new StandardSQLFunction("stuff")); registerNative(new StandardSQLFunction("replicate")); registerNative(new StandardSQLFunction("reverse")); registerNative(new StandardSQLFunction("dateadd")); registerNative(new StandardSQLFunction("current_user")); registerNative(new StandardSQLFunction("datename")); registerNative(new StandardSQLFunction("len")); registerAlias(Func.length, "len"); registerNative(new StandardSQLFunction("datalength")); registerAlias(Func.lengthb, "datalength"); registerAlias(Func.locate, "charindex"); registerNative(Func.current_timestamp, new NoArgSQLFunction("current_timestamp", false), "getutcdate", "getdate"); registerCompatible(Func.current_date, new TemplateFunction("current_date", "cast(current_timestamp as date)")); registerCompatible(Func.current_time, new TemplateFunction("current_time", "cast(current_timestamp as time)")); registerAlias(Func.now, "current_timestamp"); registerAlias("sysdate", "current_timestamp"); registerNative(Func.year); registerNative(Func.month); registerNative(Func.day); // registerCompatible("extract",new // TemplateFunction("extract","datepart(%1$s,%3$s)")); registerCompatible(Func.hour, new TemplateFunction("hour", "datepart(hour,%s)")); registerCompatible(Func.minute, new TemplateFunction("minute", "datepart(minute,%s)")); registerCompatible(Func.second, new TemplateFunction("second", "datepart(second,%s)")); registerCompatible(Func.date, new TemplateFunction("date", "cast(%s as date)")); registerCompatible(Func.time, new TemplateFunction("time", "cast(%s as time)")); registerCompatible(Func.timestampadd, new EmuSQLServerTimestamp("timestampadd", "dateadd")); registerCompatible(Func.timestampdiff, new EmuSQLServerTimestamp("timestampdiff", "datediff")); registerCompatible(Func.datediff, new TemplateFunction("datediff", "datediff(day,%2$s,%1$s)")); registerCompatible(Func.adddate, new TemplateFunction("adddate", "dateadd(day,%2$s,%1$s)"),"date_add"); registerCompatible(Func.subdate, new TemplateFunction("subdate", "dateadd(day,-%2$s,%1$s)"),"date_sub"); registerCompatible(Func.add_months, new TemplateFunction("add_months", "dateadd(month,%2$s,%1$s)")); registerCompatible(Func.mod, new TemplateFunction("mod", "(%1$s %% %2$s)")); registerCompatible(Func.decode, new EmuDecodeWithCase()); registerCompatible(Func.concat, new VarArgsSQLFunction("", "+", "")); // 没有concat函数的,要改写为相加 registerCompatible(Func.trim, new TemplateFunction("trim", "ltrim(rtrim(%s))")); // 没有concat函数的,要改写为相加 registerCompatible(Func.lpad, new TemplateFunction("lpad", "(replicate(%3$s, %2$s-len(%1$s)) + %1$s)")); registerCompatible(Func.rpad, new TemplateFunction("rpad", "(%1$s + replicate(%3$s, %2$s-len(%1$s)))")); registerCompatible(Func.trunc, new EmuSQLServerTrunc()); registerCompatible(Func.str, new TemplateFunction("str", "convert(varchar,%s,120)")); } @Override protected String getComment(AutoIncrement column, boolean flag) { StringBuilder sb = new StringBuilder(); sb.append("int identity(1,1)"); if (flag) { if (!column.nullable) sb.append(" not null"); } return sb.toString(); } public int getPort() { return 1433; } public RDBMS getName() { return RDBMS.sqlserver; } @Override public String getColumnNameToUse(AColumnMapping name) { return name.lowerColumnName(); } @Override public String getDefaultSchema() { return "dbo"; } @Override public String generateUrl(String host, int port, String pathOrName) { StringBuilder sb = new StringBuilder("jdbc:"); // jdbc:microsoft:sqlserver:@localhost:1433; DatabaseName =allandb sb.append("microsoft:sqlserver:"); sb.append("//").append(host).append(":").append(port <= 0 ? 1433 : port); sb.append("; DatabaseName=").append(pathOrName); String url = sb.toString(); return url; } public String getDriverClass(String url) { return "com.microsoft.jdbc.sqlserver.SQLServerDriver"; } public void parseDbInfo(ConnectInfo connectInfo) { JefStringReader reader = new JefStringReader(connectInfo.getUrl()); reader.setIgnoreChars(' '); reader.consumeIgnoreCase("jdbc:microsoft:sqlserver:"); reader.consumeChars('@', '/'); String host = reader.readToken(':', '/'); connectInfo.setHost(host); if (reader.omitAfterKeyIgnoreCase("databasename=", ' ') != -1) { String dbname = reader.readToken(' ', ';', ':'); connectInfo.setDbname(dbname); } reader.close(); } private final LimitHandler limit=generateLimitHander(); @Override public final LimitHandler getLimitHandler() { return limit; } protected LimitHandler generateLimitHander() { if(UnionJudgement.isDruid()){ return new SQL2000LimitHandler(); }else{ return new SQL2000LimitHandlerSlowImpl(); } } final static ParserFactory factory=new ParserFactory.SQLServer(); @Override public ParserFactory getParserFactory() { return factory; } }