Вопрос:
Для некоторых тестов интеграции я хочу подключиться к базе данных и запустить файл .sql, который имеет схему, необходимую для фактического запуска тестов, включая инструкции GO. Как я могу выполнить файл .sql? (или это совсем не тот путь?)
Я нашел сообщение в форуме MSDN, показывая этот код:
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: Модуль С++ не загружался во время Инициализация приложения. — > System.DllNotFoundException: невозможно выполнить загрузить DLL ‘MSVCR80.dll’: указанный модуль не найден. (Исключение от HRESULT: 0x8007007E).
Мне сказали пойти и скачать эту DLL откуда-то, но это звучит очень хаки. Есть ли более чистый способ? Есть ли другой способ сделать это? Что я делаю неправильно?
Я делаю это с Visual Studio 2008, SQL Server 2008,.Net 3.5SP1 и С# 3.0.
Лучший ответ:using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Smo;
Для выполнения запросов не требуется SMO. Вместо этого попробуйте использовать объект SqlCommand. Удалите их с помощью операторов. Используйте этот код для выполнения запроса:
SqlConnection conn = new SqlConnection(sqlConnectionString); SqlCommand cmd = new SqlCommand(script, conn); cmd.ExecuteNonQuery();
Также удалите ссылку на проект для SMO. Примечание: вы захотите правильно очистить ресурсы.
Обновление:
Библиотеки ADO.NET не поддерживают ключевое слово ‘GO’. Похоже, ваши варианты:
- Разберите script. Удалите ключевые слова “GO” и разделите script на отдельные партии. Выполняйте каждую партию как свою собственную SqlCommand.
- Отправьте script в SQLCMD в оболочке (ответ Дэвида Андреса).
- Используйте SMO, как код из сообщения в блоге.
Собственно, в этом случае я думаю, что SMO может быть лучшим вариантом, но вам нужно будет выяснить, почему DLL не была найдена.
Ответ №1
MSVCR80 – это среда исполнения Visual С++ 2005. Возможно, вам потребуется установить пакет времени выполнения. Подробнее см. http://www.microsoft.com/downloads/details.aspx?FamilyID=200b2fd9-ae1a-4a14-984d-389c36f85647&displaylang=en.
В дополнение к разрешению проблемы с DLL и ответам Мэтта Брунелла (что я считаю более подходящим для того, что вы пытаетесь сделать), вы можете использовать инструмент командной строки SQLCMD (из установки инструментов SQL Client) для выполнения этих 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
При такой же необходимости автоматически запускать сгенерированную базу данных script из кода я решил разобрать SQL script, чтобы удалить инструкции GO и разделить script на отдельные команды (как это предложил @MattBrunell). Удаление инструкций GO было простым, но расщепление операторов на «rn» не сработало, так как это привнесло многострочные операторы. Испытывая несколько разных подходов, я был очень удивлен, узнав, что script не нужно разделить на отдельные команды. Я просто удалил все инструкции “GO” и отправил целое script (включая комментарии) в 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 и script, сгенерированный “База данных → Задачи → Сгенерировать скрипты…”. Ниже приведены примеры команд в script:
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, над которым нужно разделить script. Мой script, который выполняется без проблем, содержит около 1800 операторов и составляет 520 кБ.
Ответ №3
Вы пытались запустить это с очень, очень простым script в файле .sql? Может быть, что-то, что просто вставляет одну строку или создает произвольную таблицу? Что-то, что очень легко проверить? По сути, этот код похож на жесткое кодирование sql, за исключением того, что вы читаете его из файла. Если вы можете заставить его работать с очень простым файлом, я бы сказал, что, вероятно, что-то не так с самой файловой структурой. Сообщение ссылалось на то, что есть некоторые положения относительно того, что может и не может быть в файле. Если ничего другого, это хорошее место для начала устранения неполадок.
Ответ №4
Вам может быть интересно:
Он представляет собой универсальное “тестовое устройство” для автоматического выполнения sql-скриптов. Существует также пример кода, и нет никаких зависимостей от каких-либо необычных сборок…
Ответ №5
Если вы добавите следующие ссылки в свой проект, исходный код будет работать нормально.
Я использую SQL 2008 Express.
Путь:
C:Program Files (x86)Microsoft SQL Server100SDKAssemblies
Файлы:
microsoft.sqlserver.smo.dll, microsoft.sqlserver.connectioninfo.dll и Microsoft.SqlServer.Management.Sdk.Sfc.dll