Правильный способ выбора сотен произвольных строк без отдельных запросов для каждого без параметров табличного значения - PullRequest
0 голосов
/ 30 января 2020

Допустим, у меня есть таблица «Персоны», и у каждого человека есть имя, отчество и фамилия.
У меня есть текстовый файл с сотнями людей, и мне нужно получить строку базы данных каждого человека из базы данных. Я должен сделать это в течение ограниченного времени, это не может занять более нескольких секунд.

В общем, предположим, что у меня большой случайный список значений и я не могу легко сделать предложение WHERE, чтобы захватить все их, поскольку они равномерно распределены по данным и миллионы строк.

Есть ли "хороший" способ сделать это на различных SQL серверах? Я знаю только два способа:

  • Запускать каждый запрос один за другим с сетевым отключением для каждого запроса

  • Объединять каждый запрос в одну большую строку и выполните этот запрос.

Первый из них оказывается очень медленным, а второй работает, но затрудняет использование параметров, так как в конечном итоге вам придется выполнить @PARAM1, @PARAM2 и так до бесконечности. Это также приводит к ограничению параметров, когда вы выбираете более тысячи строк (каждая строка не имеет ни одного номера / идентификационного ключа)

Для контекста это для SQL Server / C#, но я хотел бы знать, существует ли более общее / кроссплатформенное решение.

Также может быть полезен какой-то способ обновления, если он будет отличаться от выбора

Я понимаю, что параметры табличных значений - это вещь, но я не могу добавить дополнительные значения или определения на сервер SQL, чтобы использовать их для запросов, которые я пытаюсь выполнить, я могу контролировать только то, что происходит в моей программе.

1 Ответ

1 голос
/ 02 февраля 2020
  1. заполнил массив данными из вашего текстового файла.

  2. Создал DataTable для хранения возвращенных строк.

  3. Создание соединения и команды, затем добавление параметров в команду.

Обратите внимание, что команда и параметры создаются только один раз за пределами l oop. Только значения изменяются внутри l oop. Это позволяет Sql серверу повторно использовать план для команды.

Я заполнил сетку, чтобы показать, что было возвращено. Возможно, вы захотите поставить секундомер перед этой строкой, поскольку отображение данных является медленным процессом.

    private void Button2_Click(object sender, EventArgs e)
    {
        string[] lines = File.ReadAllLines("persons.txt");
        Person[] persons = new Person[lines.Length];
        int index = 0;
        foreach (string s in lines)
        {
            string[] arr = s.Split(',');
            persons[index] = new Person(arr[0], arr[1], arr[2]);
        }
        DataTable dt = new DataTable();
        using (SqlConnection cn = new SqlConnection(Properties.Settings.Default.CoffeeConnection))
        using (SqlCommand cmd = new SqlCommand("Select * From Person Where FirstName = @FName And MiddleName = @MName And LastName = @LName;", cn))
        {
            cmd.Parameters.Add("@FName", SqlDbType.VarChar, 100);
            cmd.Parameters.Add("@MName", SqlDbType.VarChar, 100);
            cmd.Parameters.Add("LName", SqlDbType.VarChar, 100);
            cn.Open();
            foreach (Person p in persons)
            {
                cmd.Parameters["@FName"].Value = p.firstName;
                cmd.Parameters["@MName"].Value = p.middleName;
                cmd.Parameters["@LName"].Value = p.lastName;
                dt.Load(cmd.ExecuteReader());
            }
        }
        dataGridView1.DataSource = dt;
    }
...