如何使用键值对列表查询数据库

时间:2013-11-29 21:37:36

标签: sql sql-server database

假设我有一个包含3列的表:Id,Category,Name。

我想以这种方式查询表: 给我这些行 { Category = "Cat1" AND Name = "ABC" }{ Category = "Cat2" AND Name = "ABC" }{ Category = "Cat2" AND Name = "DEF" }

如何?无需诉诸WHERE OR的大量列表 我在考虑使用IN ...但是可以将它与2列结合使用吗?

谢谢!

4 个答案:

答案 0 :(得分:5)

您可以创建临时表

create table #temp (Category varchar(50), Name varchar(50))
insert into #temp values ('Cat1', 'abc'), ('Cat2', 'cde'), ('Cat3', 'eee')

然后加入主表

select * from table1
inner join #temp
on table1.Category = #temp.Category and table1.Name = #temp.Name 

如果要从代码中使用该方法,可以使用表参数来实现。

定义表格类型:

CREATE TYPE dbo.ParamTable AS TABLE
    ( Category varchar(50), Name varchar(50) )

以及将读取数据的存储过程:

create procedure GetData(@param dbo.ParamTable READONLY)
AS
    select * from table1
    inner join @param p
    on table1.Category = p.Category and table1.Name = p.Name

然后您可以使用C#代码中的那些代码,例如:

using (var conn = new SqlConnection("Data Source=localhost;Initial Catalog=Test2;Integrated Security=True"))
{
    conn.Open();

    DataTable param = new DataTable();
    param.Columns.Add(new DataColumn("Category", Type.GetType("System.String")));
    param.Columns.Add(new DataColumn("Name", Type.GetType("System.String")));
    param.Rows.Add(new object[] { "Cat1", "abc" });

    using (var command = conn.CreateCommand())
    {
        command.CommandText = "GetData";
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.AddWithValue("@param", param);

        using (var reader = command.ExecuteReader())
        {
            // reading here
        }
    }

}

答案 1 :(得分:2)

@ Szymon的答案是最好的,但是如果你绝对需要在一个查询中做到这一点,你可以想出一个方案将两列连接成一个字符串并使用相同的方法连接候选值。然后,您可以使用IN代替一堆ANDsORs

SELECT *
FROM table
WHERE Category + ':' + Name IN ('Cat1:abc', 'Cat2:cde', 'Cat3:eee')

这有一个明显的缺点,就是永远无法利用索引。但这对于快速而肮脏的解决方案来说是件好事。

答案 2 :(得分:1)

使用Sql2008,FROM中有一个有趣的新子句VALUES:

select * 
from mytable
inner  join ( select * from (values('cat1', 'abc'),
            'cat2', 'def') as T(cat,name) ) C 
        on mytable.category = c.cat and mytable.name = c.name

答案 3 :(得分:0)

创建临时表以存储键值对。然后从主表中查询加入临时表。不像添加IN(...)那么简单,但这是我能想到的唯一方式,我相信IN(...)不具备