Как я могу выполнить .sql из С#?

Вопрос:Для некоторых тестов интеграции я хочу подключиться к базе данных и запустить файл .sql, который имеет схему, необходимую для фактического запуска тестов, включая инструкции GO. Как я могу выполнить файл .sql? (или это совсем не тот путь?) Я нашел сообщение в форуме MSDN, показывая этот код: using System.Data.SqlClient; using System.IO; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Smo; namespace

Вопрос:

Для некоторых тестов интеграции я хочу подключиться к базе данных и запустить файл .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

Оцените статью
Добавить комментарий