Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 в MS SQL из C#  [new]
sibir127
Member

Откуда:
Сообщений: 14
приветствую!
подскажите возможно ли в C# использовать для передачи в таблицу MS SQL Server данных из DataTable целиком,
конструкцию:
        DataTable table = new DataTable();

string sql = "select * into [dbo].[MAP_OESK_1] from " + table.TableName; как-то так, это не работает
            SqlCommand cmd = new SqlCommand(sql, conn);
            cmd.ExecuteNonQuery();

или
   using (SqlConnection destinationConnection = new SqlConnection(csDestination))
            {
                destinationConnection.Open();
                using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection))
                {
                    bulkCopy.DestinationTableName = table.TableName; или как-то так, здесь тоже не работает
                    bulkCopy.WriteToServer(table);


Модератор: Учимся использовать тэги оформления кода - FAQ

может такой реализации совсем нет в C#?
подскажите метод или есть примеры синтаксиса?
4 июн 18, 16:40    [21467291]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
Konst_One
Member

Откуда:
Сообщений: 10976
https://programmingwithmosh.com/csharp/using-sqlbulkcopy-for-fast-inserts/
4 июн 18, 16:57    [21467358]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 3972
sibir127
приветствую!
подскажите возможно ли в C# использовать для передачи в таблицу MS SQL Server данных из DataTable целиком,

Можно - используя user-defined table type (который нужно создать на сервере).
Но в даннум случае нужно использовать, как было написано выше, SqlBulkCopy.
4 июн 18, 17:04    [21467389]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
sibir127
Member

Откуда:
Сообщений: 14
Konst_One,

В примере предполагается, что наша DataTable имеет ту же схему, что и целевая Таблица. Мне надо передать в MS SQL данные не имеющую в приемнике таблицу. В этом и вопрос, есть ли инструмент использующий возможность команды sql
select * into TABLE from DATATABLE
в help msdn говориться, что sqlbulkcopy может передать на сервер в таблицу tempdb, но как не понятно.
5 июн 18, 12:05    [21469232]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 3972
sibir127
в help msdn говориться, что sqlbulkcopy может передать на сервер в таблицу tempdb, но как не понятно.

Обычная временная таблица в одном соединении с bulk copy:
var dt = new DataTable();
dt.Columns.Add("n", typeof(int));
dt.Columns.Add("s", typeof(string));
foreach(var n in Enumerable.Range(1, 5))
{
  var dr = dt.NewRow();
  dr["n"] = n;
  dr["s"] = new string(Enumerable.Repeat((char) (n + 64), 5).ToArray());
  dt.Rows.Add(dr);
}
using (var cnn = new SqlConnection("Data Source=.;Integrated Security=True"))
{
  cnn.Open();
  using (var cmd = new SqlCommand(@"
    create table #t (
      n int,
      s varchar(5)
    )
  ", cnn))
    cmd.ExecuteNonQuery();
  using (var bc = new SqlBulkCopy(cnn){DestinationTableName = "#t"})
    bc.WriteToServer(dt);
  using (var cmd = new SqlCommand("select * from #t", cnn))
  using (var reader = cmd.ExecuteReader())
    while(reader.Read())
      Console.WriteLine("{0}: {1}", reader.GetInt32(0), reader.GetString(1));
}

1: AAAAA
2: BBBBB
3: CCCCC
4: DDDDD
5: EEEEE
5 июн 18, 13:14    [21469493]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
sibir127
Member

Откуда:
Сообщений: 14
Сон Веры Павловны,
это тоже решение с имеющейся на сервере созданной таблицы с известным форматом данных, а у меня приходит таблица с чем-то, не известно размер и количественный с качественным содержанием в dbf от fox.
я все умудряюсь драйвером от fox в datatable запихать данные и ищу способ затащить все в БД на ms sql server 2017 из C#.
смущает что не работает sql команда
select * into
, где не надо знать, что тащишь в БД.
в SqlBulkCopy пока вижу, что нужна хоть убей таблица приемник со всеми известными.
5 июн 18, 17:00    [21470539]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 3972
sibir127
смущает что не работает sql команда
select * into
, где не надо знать, что тащишь в БД.
в SqlBulkCopy пока вижу, что нужна хоть убей таблица приемник со всеми известными.

С какого это перепугу не надо знать? У select into есть секция from, где указывается источник данных, метаданные которого прекрасно известны серверу, и он их в точности копирует в создаваемую таблицу. Без метаданных это в принципе не получится.
sibir127
это тоже решение с имеющейся на сервере созданной таблицы с известным форматом данных, а у меня приходит таблица с чем-то, не известно размер и количественный с качественным содержанием в dbf от fox.
я все умудряюсь драйвером от fox в datatable запихать данные и ищу способ затащить все в БД на ms sql server 2017 из C#.

1. Это временная таблица. Она имеется на сервере только в вашей сессии.
2. Есть DataTable - значит, метаданные получить можно. Разбирайте коллекцию Columns, генерите скрипт создания временной или постоянной таблицы (хотя за создание постоянных объектов базы в прикладном коде я бы отправлял подметать улицы), дальше - как было описано выше. Поиск в гугле по sqlbulkcopy create destination table в первой же ссылке выдает именно такое решение.
5 июн 18, 17:56    [21470764]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
sibir127
Member

Откуда:
Сообщений: 14
Сон Веры Павловны,
СПАСИБО,
хорошая идея гуглить на англоязычных ресурсах, на русском перечитываю одни и те же примеры, не рабочие.
 dataGridView1.DataSource = dt1;
            table = dt1.Copy();
            table.TableName = "dbo.dbfTable";

подскажи, а у datatable по умолчанию имя не присваивается служебное, я именовал сам так как в коде получал пустое имя.
столкнулся с проблемой выделения памяти, при копировании загруженной таблицы в 300 метров памяти не хватило.
автор
Необработанное исключение типа "System.OutOfMemoryException" в System.Data.dll

подскажи материал по обработке больших файлов, в идеале загрузить таблицу в 1,2 гига.
6 июн 18, 10:15    [21471799]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
Arm79
Member

Откуда: МО, Раменское
Сообщений: 3473
1. Передавать сразу всю таблицу можно. Ознакомьтесь с табличными параметрами MS SQL и их поддержкой в C#

2. Передавать много данных через этот механизм нельзя. Это просто нелепо. Для массовых загрузок используется соответствующий механизм, например SqlBulkCopy
6 июн 18, 10:29    [21471820]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2315
sibir127,

для заливки больших объемов лучше всего сделать свою (специально заточенную) имплементацию IDataReader (ну и использовать SqlBulkCopy.WriteToServer(IDataReader))
6 июн 18, 10:53    [21471910]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 3972
sibir127
подскажи материал по обработке больших файлов, в идеале загрузить таблицу в 1,2 гига.

DataTable.CreateDataReader+SqlBulkCopy.WriteToServer(IDataReader)
Или сразу передавать в SqlBulkCopy.WriteToServer тот датаридер, которым формируется DataTable (и DataTable в этом случае вообще не нужна).
6 июн 18, 11:29    [21472032]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
sibir127
Member

Откуда:
Сообщений: 14
Сон Веры Павловны,
приветствую, не смог побороть загрузку из datareader
вот код, использую два подключения одно на dbf файл, другое в ms sql server, но не получается запустить sqlblkcopy(datareader).
убрал закрытие коннекта к dbf файлу, но дальше эксперимент встал, как вкопанный.
все останавливается на строке с коментарием //Недопустимая попытка вызвать FieldCount при закрытом устройстве чтения. или Недопустимая попытка вызвать GetSchemaTable при закрытом устройстве чтения.//?????
видимо я недопонимаю логики работы с datareader(
 public partial class Form1 : Form
    {
        IDataReader sqlReader;
        DataTable table;
        Exception exce = new Exception();
        DateTime DayT = new DateTime();
        string sDirPath;
        string OFDfilename;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //string FilePath = "C:\\Work\\TestDBF\\"; //здесь файлы для работы
            string FilePath = sDirPath;
            DayT = DateTime.Now;

            OleDbConnection oledbconnection = new OleDbConnection();
            oledbconnection.ConnectionString = @"Provider=VFPOLEDB.1;Data Source=" + FilePath + "";
            oledbconnection.Open();
            Console.WriteLine(oledbconnection.ConnectionString.ToString()); //сомнения в коректности кода
            OleDbCommand oCmd = oledbconnection.CreateCommand();
            oCmd.CommandText = "SELECT * FROM " + OFDfilename;

            DataTable dt1 = new DataTable();
            sqlReader = oCmd.ExecuteReader(); //?
            dt1.Load(sqlReader);
            //dt1.Load(oCmd.ExecuteReader());
            //oledbconnection.Close();

            progressBar1.Maximum = dt1.Columns.Count;
            dataGridView1.DataSource = dt1;
            dataGridView1.Visible = true;
            table = dt1.Copy();
            table.TableName = "dbo.dbfTable" +DayT.Day+DayT.Hour+DayT.Minute;
            Console.WriteLine(table.TableName);
            textBox4.Text = exce.Message;
            textBox4.Visible = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.Title = "Select a *.dbf File";
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                OFDfilename = openFileDialog1.FileName;
                //sDirPath = openFileDialog1.InitialDirectory;
                sDirPath = Path.GetDirectoryName(OFDfilename);
                Console.WriteLine(OFDfilename);
                Console.WriteLine(sDirPath);
                comboBox1.Text = OFDfilename;
                comboBox1.Items.Add(OFDfilename);
                //int count = comboBox1.Items.Count;
                //if (count == 6) comboBox1.Items.RemoveAt(0);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            string sTableName="dbo.dbfTable" + DayT.Day + DayT.Hour + DayT.Minute;
            string csDestination = "Data Source=VLR1-STEN01;User ID=******;Password=********;" +
            "Initial Catalog=Test;MultipleActiveResultSets=true";
            SqlConnection sqlcon = new SqlConnection();
            sqlcon.ConnectionString = csDestination;
            sqlcon.Open();
            // checking whether the table selected from the dataset exists in the database or not
            string exists = null;
            try
            {
                string sqlSelect = "SELECT * FROM sysobjects where name = '" + table.TableName + "'";
                Console.WriteLine(sqlSelect);
                SqlCommand cmd = new SqlCommand(sqlSelect, sqlcon);
                textBox4.Text = exce.Message;
                textBox4.Visible = true;
                exists = cmd.ExecuteScalar().ToString();
            }
            catch (Exception exce)
            {
                exists = null;
            }

            // if does not exist
            if (exists == null)
            {
                // selecting each column of the datatable to create a table in the database
                foreach (DataColumn dc in table.Columns)
                {
                    progressBar1.PerformStep();
                    if (exists == null)
                    {
                        string sqlCreate = "CREATE TABLE " + table.TableName + "(" + dc.ColumnName + " varchar(MAX))";
                        Console.WriteLine(sqlCreate);

                    SqlCommand createtable = new SqlCommand(sqlCreate, sqlcon);
                    createtable.ExecuteNonQuery();
                    exists = table.TableName;
                    }
                    else
                    {
                        string sqlAlter = "ALTER TABLE " + table.TableName + " ADD " + dc.ColumnName + " varchar(MAX)";
                        Console.WriteLine(sqlAlter);
                    SqlCommand addcolumn = new SqlCommand(sqlAlter, sqlcon);
                    addcolumn.ExecuteNonQuery();
                    }
                }
                // copying the data from datatable to database table
                using (SqlBulkCopy bulkcopy = new SqlBulkCopy(sqlcon))
                {
                    try
                    {
                        bulkcopy.DestinationTableName = table.TableName;
                        bulkcopy.WriteToServer(sqlReader); //Недопустимая попытка вызвать FieldCount при закрытом устройстве чтения.  или Недопустимая попытка вызвать GetSchemaTable при закрытом устройстве чтения.//?????
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }
            // if table exists, just copy the data to the destination table in the database
            else
            {
                using (SqlBulkCopy bulkcopy = new SqlBulkCopy(sqlcon))
                {
                    try
                    {
                        bulkcopy.DestinationTableName = table.TableName;
                        bulkcopy.WriteToServer(sqlReader);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
            }
            sqlcon.Close();
            Console.WriteLine("Successfully to update the table.");
            textBox3.Text = "Сворачивай манатки, все...";
            textBox3.Visible = true;
            textBox4.Text = exce.Message;
            textBox4.Visible = true;
        }
9 июн 18, 14:56    [21482130]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
Konst_One
Member

Откуда:
Сообщений: 10976
table - что это такое у вас за объект?
9 июн 18, 15:00    [21482145]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
Konst_One
Member

Откуда:
Сообщений: 10976
сделайте нормальные методы с передачей всех нужных параметров, а то вообще непонятно, что вы там делаете, какой-то дельфи-стайл с кнопками и глобальными переменными
9 июн 18, 15:03    [21482159]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2315
sibir127,

            sqlReader = oCmd.ExecuteReader(); //?
            dt1.Load(sqlReader);

Вероятней всего, после этого, sqlReader - "закрытое устройство чтения" (обычно Reader-ы "forward only", без "reset init state")
P.S. Это если пользователь-обезьянка нажимает сначала button1, а затем button2 и button3...
10 июн 18, 22:16    [21484000]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
sibir127
Member

Откуда:
Сообщений: 14
LR,

Приветствую! То есть вопрос не во втором подключении к sql приёмнику, я думал проблема в двойном подключении сразу и к dbf и sql, а реадер один выбирает и он же отдает. И он где то закрывается перед выгрузкой данных.
13 июн 18, 10:27    [21487520]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2315
sibir127
где то закрывается

The Visual Studio debugger helps you observe the run-time behavior of your program and find problems.
13 июн 18, 11:00    [21487664]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
sibir127
Member

Откуда:
Сообщений: 14
LR,

Спасибо, да закрытие нашел. У Вас есть пример импорта таблицы из reader, не могу найти решение.
из datatable получается при создании в приемнике структуры таблицы, но с sqlbulkcopy из datareader построить не получается.
Если создаю datatable то Вы мне показали, что datareader тут-же закрывается.
13 июн 18, 13:48    [21488262]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2315
sibir127,

Сон Веры Павловны
Или сразу передавать в SqlBulkCopy.WriteToServer тот датаридер, которым формируется DataTable (и DataTable в этом случае вообще не нужна).

т.е., так пробовали?
            sqlReader = oCmd.ExecuteReader();
            //dt1.Load(sqlReader);
            bulkcopy.WriteToServer(sqlReader);
13 июн 18, 14:05    [21488368]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
sibir127
Member

Откуда:
Сообщений: 14
LR,
да, создаю новое соединение передаю в sqlbulkcopy, но при указании table.TableName(здесь имя таблицы), ругается, что нет доступа к таблице приемнику.
 sqlbulkcopy.DestinationTableName = table.TableName;
13 июн 18, 15:04    [21488613]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2315
sibir127,

Ну, т.е., таблицы в БД наверное нет? Тогда можно использовать OleDbDataReader.GetSchemaTable() для создания таблицы "в приемнике". Можно, конечно, и так "коряво" как Вы делали (с предварительной заливкой данных в DataTable), но тогда открывайте два DataReader-а, один для создания DataTable, второй - для SqlBulkCopy.
13 июн 18, 16:30    [21488955]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2315
sibir127,

а почему бы один раз не сделать необходимую(ые) таблицу(ы) "в приемнике" и не мучиться проверкой/созданием?
13 июн 18, 16:40    [21488990]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
sibir127
Member

Откуда:
Сообщений: 14
LR,
Коряво, ))) потому что реализация планировалась через datatable, пока не познакомился с datareader, а при пришедшем файле более 300 Мб все это тоже развалилось, не хватает памяти.
тут послали меня на SqlBulkCopy и вот побороть самостоятельно не выходит, все примеры не содержат полную реализацию, самую простую, все примеры не рабочие.
13 июн 18, 21:45    [21489594]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
LR
Member

Откуда: 8P8C
Сообщений: 2315
sibir127
и вот побороть самостоятельно не выходит, все примеры не содержат полную реализацию, самую простую, все примеры не рабочие.

Ну это только так кажется. Не поддавайтесь унынию (уныние - величайший из грехов, лучше кого-нибудь убить чем унывать). Еще раз спрошу, почему Вы не хотите создать таблицу-приемник "вручную", один раз, и затем не иметь никаких проблем с SqlBulkCopy?
14 июн 18, 00:38    [21489805]     Ответить | Цитировать Сообщить модератору
 Re: в MS SQL из C#  [new]
sibir127
Member

Откуда:
Сообщений: 14
LR,

Причина во вредности характера, мне ткнули здесь, что делается это элементарно через "ленивую загрузку", а по жизни выяснилось, что руки у всех разные и при достигнутой договорённости формат и содержание в самый неподходящий момент оказываются отличными от первоначальных. решил что нужно это теперь узнать и сделать, а то спать не буду)
14 июн 18, 07:53    [21489934]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / WinForms, .Net Framework Ответить