对于某些集成测试,我想连接到数据库并运行一个.sql文件,该文件具有测试实际运行所需的模式,包括GO语句。我怎么能执行.sql文件? (或者这完全是错误的方式?)
我发现a post in the MSDN forum显示了此代码:
using System.Data.SqlClient;
using System.IO;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string sqlConnectionString = "Data Source=(local);Initial Catalog=AdventureWorks;Integrated Security=True";
FileInfo file = new FileInfo("C:\\myscript.sql");
string script = file.OpenText().ReadToEnd();
SqlConnection conn = new SqlConnection(sqlConnectionString);
Server server = new Server(new ServerConnection(conn));
server.ConnectionContext.ExecuteNonQuery(script);
}
}
}
但是在最后一行我收到了这个错误:
System.Reflection.TargetInvocationException: 例外已被抛出 调用的目标。 ---> System.TypeInitializationException: ''的类型初始值设定项 抛出一个例外。 ---> .ModuleLoadException: C ++模块在加载期间无法加载 appdomain初始化。 ---> System.DllNotFoundException:无法执行 加载DLL'MSVCR80.dll':指定的 无法找到模块。 (例外 来自HRESULT:0x8007007E)。
我被告知要从某个地方下载该DLL,但这听起来非常hacky。有更清洁的方式吗?还有另一种方法吗?我做错了什么?
我正在使用Visual Studio 2008,SQL Server 2008,.Net 3.5SP1和C#3.0执行此操作。
答案 0 :(得分:29)
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
您不应该需要SMO来执行查询。请尝试使用SqlCommand对象。删除这些using语句。使用此代码执行查询:
SqlConnection conn = new SqlConnection(sqlConnectionString);
SqlCommand cmd = new SqlCommand(script, conn);
cmd.ExecuteNonQuery();
此外,删除对SMO的项目引用。注意:您需要正确清理资源。
ADO.NET库do not support the 'GO' keyword。看起来你的选择是:
实际上,在这种情况下,我认为SMO可能是最佳选择,但您需要找出未找到dll的原因。
答案 1 :(得分:9)
MSVCR80是Visual C ++ 2005运行时。您可能需要安装运行时包。有关详细信息,请参阅http://www.microsoft.com/downloads/details.aspx?FamilyID=200b2fd9-ae1a-4a14-984d-389c36f85647&displaylang=en。
除了解决DLL问题和Matt Brunell的答案(我觉得它更适合你要做的事情),你可以使用SQLCMD命令行工具(来自SQL客户端工具安装)来执行这些SQL脚本。请确保它在您的路径上,这样您就不会对路径位置感到困惑。
这样就可以了:
实际命令:
SQLCMD -S myServer -D myDatabase -U myUser -P myPassword -i myfile.sql
参数(案例事项):
S: server
d: database
U: User name, only necessary if you don't want to use Windows authentication
P: Password, only necessary if you don't want to use Windows authentication
i: File to run
执行SQL文件的代码:
var startInfo = new ProcessStartInfo();
startInfo.FileName = "SQLCMD.EXE";
startInfo.Arguments = String.Format("-S {0} -d {1}, -U {2} -P {3} -i {4}",
server,
database,
user,
password,
file);
Process.Start(startInfo);
有关SQLCMD工具的更多信息,请参阅http://msdn.microsoft.com/en-us/library/ms162773.aspx。
答案 2 :(得分:2)
同样需要从代码自动运行生成的数据库脚本,我开始解析SQL脚本以删除GO语句并将脚本拆分为单独的命令(如@MattBrunell所建议的那样)。删除GO语句很容易,但是在"\r\n"
上拆分语句不起作用,因为这搞砸了多行语句。测试几种不同的方法,我很惊讶地发现脚本根本不必拆分成单独的命令。我刚刚删除了所有“GO”语句,并将整个脚本(包括注释)发送到SqlCommand:
using System.Data.SqlClient;
using(SqlConnection connection = new SqlConnection(connectionString))
using(SqlCommand command = connection.CreateCommand())
{
string script = File.ReadAllText("script.sql");
command.CommandText = script.Replace("GO", "");
connection.Open();
int affectedRows = command.ExecuteNonQuery();
}
此代码已使用SQL Server 2008 R2和“数据库 - >任务 - >生成脚本...”生成的脚本进行了测试。以下是脚本中命令的一些示例:
USE [MyDatabase]
ALTER TABLE [MySchema].[MyTable] DROP CONSTRAINT [FK_MyTable_OtherTable]
DROP TABLE [MySchema].[MyTable]
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
/****** Object: Table [MySchema].[MyTable] Script Date: 01/23/2013 13:39:29 ******/
CREATE TABLE [MySchema].[MyTable](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Subject] [nvarchar](50) NOT NULL,
[Body] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
SET IDENTITY_INSERT [MySchema].[MyTable] ON
INSERT [MySchema].[MyTable] ([Id], [Subject], [Body]) VALUES (1, N'MySubject', N'Line 1
Line 2
Line 3
Multi-line strings are also OK.
')
SET IDENTITY_INSERT [MySchema].[MyTable] OFF
我猜单个SqlCommand可能有一些最大长度,超过该长度必须拆分脚本。我的脚本执行没有问题,包含大约1800个语句,是520 kB。
答案 3 :(得分:0)
您是否尝试使用.sql文件中非常非常基本的脚本运行它?也许只是插入一行或创建一个任意表的东西?什么东西很容易验证?本质上,这个代码就像对sql进行硬编码一样,除非你是从文件中读取它。如果你可以使用一个非常简单的文件,那么我会说文件结构本身可能有问题。该帖提到了这样一个事实,即对文件中可以存在和不存在的内容有一些规定。如果不出意外,它是开始排除故障的好地方。
答案 4 :(得分:0)
您可能对此感兴趣: http://geekswithblogs.net/thomasweller/archive/2009/09/08/automating-database-script-execution.aspx
它提供了一个通用的“测试夹具”来自动执行sql脚本。还有可用的示例代码,并且不依赖于任何不寻常的程序集......
答案 5 :(得分:0)
如果在项目中添加以下引用,则原始代码将正常工作。
我使用SQL 2008 Express。
路径: C:\ Program Files(x86)\ Microsoft SQL Server \ 100 \ SDK \ Assemblies \
文件: microsoft.sqlserver.smo.dll,microsoft.sqlserver.connectioninfo.dll和Microsoft.SqlServer.Management.Sdk.Sfc.dll