SQL-запрос - выберите из списка элементов / кортежей - PullRequest
3 голосов
/ 08 ноября 2011

У меня есть список объектов, которые я извлек из вызова веб-службы, и мне нужно сопоставить их с некоторыми строками в одной из моих таблиц базы данных.У моего объекта есть несколько свойств:

Name - string
Type - string

Вместе Имя и Тип возвращают уникальный элемент в моей базе данных:

SELECT * FROM dbo.MyTable WHERE SomeName = @Name AND SomeType = @Type

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

List<Tuple> values = [{ "Name1", "Type1" }, { "Name2", "Type2" }, { "Name3", "Type3" }]

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

Ответы [ 3 ]

2 голосов
/ 08 ноября 2011

Вы можете использовать Табличные параметры в SQL Server 2008 (ADO.NET) .

SQL

CREATE TYPE [dbo].[MyTableType] AS TABLE
(
    [SomeName] NVARCHAR(50),
    [SomeType] NVARCHAR(50)
)

CREATE TABLE [dbo].[MyTable]
(
    [SomeName] NVARCHAR(50),
    [SomeType] NVARCHAR(50)
)

INSERT  [dbo].[MyTable]
VALUES  ('Name1', 'Type1'),
        ('Name2', 'Type2'),
        ('Name3', 'Type3'),
        ('Name4', 'Type4')

C #

var values = new List<Tuple<string, string>> { Tuple.Create("Name1", "Type1"), Tuple.Create("Name2", "Type2"), Tuple.Create("Name3", "Type3") };

var dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn("SomeName", typeof(string)));
dataTable.Columns.Add(new DataColumn("SomeType", typeof(string)));

values.ForEach(v => dataTable.Rows.Add(v.Item1, v.Item2));

using (var connection = new SqlConnection(@"Data Source=.;Initial Catalog=Tom;Integrated Security=True"))
{
    using (var command = new SqlCommand())
    {
        command.Connection = connection;
        command.CommandText =
            "SELECT * " +
            "FROM [dbo].[MyTable] mt " +
            "INNER JOIN @MyTableType mtt " +
            "   ON mt.[SomeName] = mtt.[SomeName] " +
            "   AND mt.[SomeType] = mtt.[SomeType]";

        SqlParameter parameter = command.Parameters.AddWithValue("@MyTableType", dataTable);
        parameter.SqlDbType = SqlDbType.Structured;
        parameter.TypeName = "[dbo].[MyTableType]";

        connection.Open();
        SqlDataReader reader = command.ExecuteReader();

        while (reader.Read())
        {
            Console.WriteLine("mt.[SomeName]: {0}, mt.[SomeType]: {1}, mtt.[SomeName]: {2}, mtt.[SomeType]: {3}", 
                reader.GetString(0), reader.GetString(1), reader.GetString(2), reader.GetString(3));
        }
    }
}

Console.ReadKey();
1 голос
/ 08 ноября 2011

Несколько вариантов, которые я могу придумать, вне головы:

1) Переберите список значений и динамически создайте запрос, подобный следующему:

SELECT *
FROM dbo.MyTable
WHERE (SomeName = values[0][0] and SomeType = values[0][1])
   OR (SomeName = values[1][0] and SomeType = values[1][1])
   OR (SomeName = values[2][0] and SomeType = values[2][1])

2) Вставьте список во временную таблицу и выполните запрос как простое объединение:

CREATE TABLE #tuples
(Name varchar(max), Type varchar(max))

--Insert the list into the #tuples table (several ways to do this)

SELECT *
FROM dbo.MyTable m
  join #tuples t on m.SomeName = t.Name
                and m.SomeType = t.Type

DROP TABLE #tuples
0 голосов
/ 08 ноября 2011

Не могли бы вы перебрать список values, выполнив запрос, который каждый раз возвращает один элемент из базы данных, и добавить каждый результат в список в коде вашего приложения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...