我的应用程序中有一些选项组合,用户可以从中进行选择,因此可以从SQL Server查询以获取一些结果
假设用户选择组合:
Option1 - Item1
Option1 - Item2
Option2 - Item1
数据库表:
Option1 Item1 Details1 Details2 Details3
Option1 Item2 Details4 Details5 Details6
Option1 Item3 Details7 Details8 Details9
Option1 Item4 Details10 Details11 Details12
...
Option2 Item1 Details13 Details14 Details15
选择时,将检索上述选项 - 项目组合,并检索其相应的详细信息。
如何通过在查询中传递Option-Item组合来获取这些详细信息? 我试过像:
SELECT * FROM tbData
WHERE Strategy IN ('Option1','Option2')
AND Items IN ('Item1','Item2')
......但这给出了错误的答案。
答案 0 :(得分:0)
你不能那样使用IN
。你需要说:
WHERE (Strategy = 'Option1' AND Items IN ('Item1', 'Item2'))
OR (Strategy = 'Option2' AND Items IN ('Item1'))
这是因为每列上的IN
分别表示“返回策略为任意值的任何行(选项1或选项2),而项目是(第1项或第2项)中的任何值。”您不能单独应用这两个概念,并希望SQL Server知道Item2仅适用于Option1。
现在,另一种选择是使用表值参数。因此,您可以在SQL Server中按如下方式定义表类型:
CREATE TYPE dbo.Options AS TABLE
(
Strategy VARCHAR(32),
Items VARCHAR(32)
);
使用所选选项在C#中填充DataTable,然后将其传入。您的查询变为:
CREATE PROCEDURE dbo.whatever
@tvp dbo.Options READONLY
AS
BEGIN
SELECT d.* FROM tbData AS d
INNER JOIN @tvp AS t
ON d.Strategy = t.Strategy
AND d.Items = t.Items;
END
GO
编辑添加另一个选项。
如果您可以将选项集作为双重分隔字符串传递到表中,例如
@Options = 'Option1,Item1;Option1,Item2;Option2,Item1'
然后你可以使用表值函数,例如
CREATE FUNCTION dbo.SplitMultiStrings
(
@List VARCHAR(MAX),
@d1 CHAR(1),
@d2 CHAR(1)
)
RETURNS TABLE
AS
RETURN
(
SELECT x, y FROM
(
SELECT
x = i.i.value('(./x/text())[1]', 'varchar(32)'),
y = i.i.value('(./y/text())[1]', 'varchar(32)')
FROM (
SELECT [XML] = CONVERT(XML, '<i><x>'
+ REPLACE(REPLACE(@List, @d1, '</x><y>'),
@d2, '</y></i><i><x>') + '</y></i>')
) AS x CROSS APPLY [XML].nodes('i') AS i(i)
) AS y WHERE x IS NOT NULL AND y IS NOT NULL
);
GO
现在你可以说:
CREATE PROCEDURE dbo.whatever
@Options VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
SELECT d.*
FROM dbo.SplitMultiStrings(@List, ',', ';') AS o
INNER JOIN tbData AS d
ON o.x = d.Strategy AND o.y = d.Items;
END TRY
BEGIN CATCH
RAISERROR('You probably have a trailing ; or other formatting issue.', 11, 1);
END CATCH
END
GO
然后以这种方式调用存储过程(通过从应用程序传递此逗号/分号分隔的字符串):
EXEC dbo.whatever @Options = 'Option1,Item1;Option1,Item2;Option2,Item1';
但我仍然认为TVP选项是要走的路。