【发布时间】:2015-11-10 11:55:21
【问题描述】:
当我尝试使用 SchemaCrawler API 从 SQL Server 数据库中检索存储过程时,我收到以下错误:
12:28:07.427 [main] INFO schemacrawler.crawl.SchemaCrawler - Retrieving routines
12:28:07.767 [main] WARN schemacrawler.crawl.RoutineRetriever - JDBC driver does not support retrieving functions
java.lang.AbstractMethodError: null
at net.sourceforge.jtds.jdbc.JtdsDatabaseMetaData.getFunctions(JtdsDatabaseMetaData.java:3570) ~[jtds-1.3.1.jar:1.3.1]
at schemacrawler.crawl.RoutineRetriever.retrieveFunctions(RoutineRetriever.java:175) ~[schemacrawler-14.02.02.jar:na]
at schemacrawler.crawl.SchemaCrawler.crawlRoutines(SchemaCrawler.java:214) [schemacrawler-14.02.02.jar:na]
at schemacrawler.crawl.SchemaCrawler.crawl(SchemaCrawler.java:564) [schemacrawler-14.02.02.jar:na]
at schemacrawler.utility.SchemaCrawlerUtility.getCatalog(SchemaCrawlerUtility.java:49) [schemacrawler-14.02.02.jar:na]
at schemacrawler.utility.SchemaCrawlerUtility.getCatalog(SchemaCrawlerUtility.java:57) [schemacrawler-14.02.02.jar:na]
at com.expedia.cgs.db.ExportScripts.main(ExportScripts.java:41) [classes/:na]
jtds 驱动支持DatabaseMetaData.getProcedures(),但不支持DatabaseMetaData.getFunctions()。有解决办法吗?
更新:这是我的代码:
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.slf4j.bridge.SLF4JBridgeHandler;
import schemacrawler.schema.Catalog;
import schemacrawler.schema.Column;
import schemacrawler.schema.Routine;
import schemacrawler.schema.Schema;
import schemacrawler.schema.Table;
import schemacrawler.schema.View;
import schemacrawler.schemacrawler.DatabaseConnectionOptions;
import schemacrawler.schemacrawler.RegularExpressionInclusionRule;
import schemacrawler.schemacrawler.SchemaCrawlerException;
import schemacrawler.schemacrawler.SchemaCrawlerOptions;
import schemacrawler.schemacrawler.SchemaInfoLevelBuilder;
import schemacrawler.utility.SchemaCrawlerUtility;
public class ExportScripts {
public static void main(String[] args) throws SchemaCrawlerException, SQLException {
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
// Create a database connection
final DataSource dataSource = new DatabaseConnectionOptions("jdbc:sqlserver://myDatabase;appName=SchemaCrawler;useCursors=true");
final Connection connection = dataSource.getConnection("username", "password");
// Create the options
final SchemaCrawlerOptions options = new SchemaCrawlerOptions();
// Set what details are required in the schema - this affects the
// time taken to crawl the schema
options.setSchemaInfoLevel(SchemaInfoLevelBuilder.standard());
options.setRoutineInclusionRule(new RegularExpressionInclusionRule("ContentGeneration\\.dbo.*"));
options.setSchemaInclusionRule(new RegularExpressionInclusionRule("ContentGeneration\\.dbo.*"));
// Get the schema definition
final Catalog catalog = SchemaCrawlerUtility.getCatalog(connection,
options);
for (final Schema schema : catalog.getSchemas()) {
System.out.println(schema);
for (final Routine routine : catalog.getRoutines()) {
System.out.println("r--> " + routine);
System.out.println("definition: " + routine.getDefinition());
}
for (final Table table : catalog.getTables(schema)) {
System.out.print("o--> " + table);
if (table instanceof View) {
System.out.println(" (VIEW)");
} else {
System.out.println();
}
for (final Column column : table.getColumns()) {
System.out.println(" o--> " + column + " ("
+ column.getColumnDataType() + ")");
}
}
}
}
}
【问题讨论】:
-
发送查询而不是使用 SchemaCrawler,例如
SELECT o.name, m.definition FROM sys.objects INNER JOIN sys.sql_modules... -
@AaronBertrand 这行得通,但我不得不将您的查询修改为
SELECT o.name, m.definition FROM sys.objects o INNER JOIN sys.sql_modules m ON m.object_id=o.object_id。也就是说,我们可以让 SchemaCrawler 做到这一点吗?还是这个功能不存在? -
是的,我的评论只是一个一般性的想法,而不是工作代码。而且我不知道 SchemaCrawler。我发现大多数像这样的助手倾向于把简单的东西做对,但是当你需要一些异国情调的东西时就会崩溃(我不愿称函数为异国情调)。
-
你可以让 SchemaCrawler 使用这个查询。看看sualeh.github.io/SchemaCrawler/INFORMATION_SCHEMA.html
-
另外,请提供更多详细信息,例如您正在使用的命令行。