我开发了一个具有备份和恢复功能的好应用程序。它工作正常。每次我向SQL Server 2008 R2数据库添加新功能时,例如添加新的存储过程或用户定义的表类型来升级我的软件。
我的备份功能是:
protected int BackUpDataBase(string dbName, string address)
{
try
{
using (_con)
{
string command = "Backup database " + dbName + " to disk='" + address + "'";
SqlCommand cmd = new SqlCommand(command, _con);
cmd.CommandType = CommandType.Text;
connect();
cmd.ExecuteNonQuery();
return 1;
}
}
catch (SqlException ex)
{
return ex.Number * (-1);
}
}
我的恢复功能在这里:
protected int RecoverDataBase(string dbName, string address)
{
try
{
SqlConnection temp = new SqlConnection(_addressMaster);
string Restore = "USE master" + Environment.NewLine;
if (CheckDatabaseExists(dbName))
{
Restore += @"ALTER DATABASE [" + dbName + "]" + Environment.NewLine;
Restore += @"SET OFFLINE WITH ROLLBACK IMMEDIATE" + Environment.NewLine;
Restore += @"ALTER DATABASE [" + dbName + "] SET ONLINE" + Environment.NewLine;
}
Restore += @"RESTORE DATABASE [" + dbName + "] FROM DISK = N'" + address + @"' WITH FILE = 1, NOUNLOAD, REPLACE, STATS = 10" + Environment.NewLine;
Restore += @"ALTER DATABASE [" + dbName + "] SET Single_User WITH Rollback Immediate" + Environment.NewLine;
Restore += @"ALTER DATABASE [" + dbName + "] SET Multi_User" + Environment.NewLine;
using (temp)
{
using (SqlCommand cmd = new SqlCommand(Restore, temp))
{
cmd.CommandText = Restore;
cmd.CommandType = CommandType.Text;
temp.Open();
cmd.ExecuteNonQuery();
temp.Close();
return 1;
}
}
}
catch (SqlException ex)
{
return ex.Number * (-1);
}
}
一切都很好但是!问题出在这里:我使用新的存储过程等开发了我升级的Windows应用程序,然后将其安装到新计算机并希望将旧备份恢复到我升级的应用程序,所有新的存储过程和功能将返回到旧,因为我已恢复整个旧备份不仅仅是它的数据。 那么如何使用C#和SQL查询从备份文件中仅恢复表数据?
答案 0 :(得分:1)
您无法仅恢复数据,但可以在恢复备份之前编写所有对象模块的脚本(可以使用SSMS通过鼠标单击执行此操作),然后删除所有模块并启动重新创建的脚本所有模块。
更新:
如果您不能使用SSMS,则可以使用
编写模块脚本select definition from sys.sql_modules
作为CREATE语句。 这里唯一需要注意的是,不能重命名对象,因为重命名模块时sys.sql_modules中的定义不会更新。
其他选项包括:
答案 1 :(得分:1)
在另一个数据库(副本或现有开发/测试环境)上恢复数据库。
然后只选择所需数据并将其复制到生产环境。
选择数据并将其插回的方式完全取决于要传输的数据,以及是否有任何约束来添加数据(索引,键等等)
例如,您可以在此处获取所有STORED PROCEDURE名称。
SELECT 'DROP PROCEDURE ' + objects.name FROM sys.sql_modules
INNER JOIN sys.objects
ON objects.object_id = sql_modules.object_id
WHERE objects.type_desc = 'SQL_STORED_PROCEDURE'
然后,您可以使用以下查询恢复创建脚本
SELECT sql_modules.definition FROM sys.sql_modules
INNER JOIN sys.objects
ON objects.object_id = sql_modules.object_id
WHERE objects.type_desc = 'SQL_STORED_PROCEDURE'
只需将它们放在EXEC
中,并确保它在生产数据库上执行,并从复制数据库中选择数据。
DROP TABLE [prodDB].[mySchema].[myTable]
SELECT * INTO [prodDB].[mySchema].[myTable] FROM [copyDB].[mySchema].[myTable]
您还可以再次从sys.objects
表中获取表格定义。
SELECT schemas.name + '.' + objects.name FROM sys.objects
INNER JOIN sys.schemas
ON objects.schema_id = schemas.schema_id
WHERE type_desc = 'USER_TABLE'
TRUNCATE TABLE [prodDB].[mySchema].[myTable]
INSERT INTO [prodDB].[mySchema].[myTable] SELECT * FROM [copyDB].[mySchema].[myTable]
如果您有任何外键引用已恢复的表格,请考虑阅读此帖子:https://stackoverflow.com/a/253858/3635715
如果您需要获取密钥定义,可以从[sys].[key_constraints]