我正在尝试在运行时创建一个测试数据库(基于我的生产数据库),而不是必须维护一个完全重复的测试数据库我想在运行时复制生产数据库的整个数据结构然后当我关闭测试数据库时,删除整个数据库。
我假设我将使用如下语句:
CREATE DATABASE test //to create the test db
CREATE TABLE test.sampleTable LIKE production.sampleTable //to create each table
当我完成测试数据库时,调用close方法将运行类似:
DROP DATABASE test //delete the database and all its tables
但是如何自动查找生产数据库中的所有表而无需手动将其写出来。我的想法是,我可以操作我的生产数据库,而不必担心在测试数据库中保持相同的结构。
在这种情况下是否需要存储过程?关于如何实现这样的事情的一些示例代码将不胜感激。
答案 0 :(得分:0)
在脚本语言中,您要在要复制的数据库上调用“SHOW TABLES”。读取结果一次设置一行,程序将表的名称放入变量(让我们称之为$ tablename)并生成sql:“CREATE TABLE test。$ tablename LIKE production。$ tablename”。迭代结果集,你就完成了。
(你不会以这种方式获得外键约束,但也许你不需要那些。如果你这样做,你可以运行“SHOW CREATE TABLE $ tablename”并解析结果以挑选约束。)< / p>
我没有java的代码片段,但是这里有一个perl可以作为伪代码处理:
$ref = $dbh->selectall_arrayref("SHOW TABLES");
unless(defined ($ref)){
print "Nothing found\n";
} else {
foreach my $row_ref (@{$ref}){
push(@tables, $row_ref->[0]);
}
}
foreach语句迭代数据库接口库返回的数组引用中的结果集。 push语句将结果集的当前行的第一个元素放入数组变量@tables中。您将使用适合您所选语言的数据库库。
答案 1 :(得分:0)
如果您使用的数据库驱动程序支持它,则可以使用DatabaseMetaData#getTables获取架构的表列表。您可以从Connection#getMetaData访问DatabaseMetaData。
答案 2 :(得分:0)
我会使用mysqldump:http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html
它将生成一个包含复制prod数据库所需的所有sql命令的文件
答案 3 :(得分:0)
解决方案如下:
private static final String SQL_CREATE_TEST_DB = "CREATE DATABASE test";
private static final String SQL_PROD_TABLES = "SHOW TABLES IN production";
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute(SQL_CREATE_TEST_DB);
SqlRowSet result = jdbcTemplate.queryForRowSet(SQL_PROD_TABLES);
while(result.next()) {
String tableName = result.getString(result.getMetaData().getColumnName(1)); //Retrieves table name from column 1
jdbcTemplate.execute("CREATE TABLE test2." + tableName + " LIKE production." + tableName); //Create new table in test2 based on production structure
}
这是使用Spring来简化数据库连接等,但真正的神奇之处在于SQL语句。正如D Mac所提到的,这不会复制外键约束,但可以通过运行另一个SQL语句并解析结果来实现。