我有一个执行存储过程的应用程序。有一个组合框“城市”,用户只能选择一个值,我将该值用作我的 C# 代码中的 SQL 参数。
简化示例:
Select StudentName, Age
From dbo.Students
Where City = @city
@city 被组合框中的值替换。
现在需求改了,组合框支持多选。所选元素存储在数组中。现在我正在使用以下方法。
- 使用 String.Join("','") 连接数组元素并将结果分配给@city。
更改查询以使用 IN 运算符。
选择学生姓名、年龄
来自 dbo.Students
所在城市 IN (@city)
假设选择的城市是伦敦和悉尼,那么@City 变成伦敦','悉尼。然后在 SP 中它将被用作 'London','Sydney' 这在句法上是正确的。但是这个查询失败了。
我做错了什么?
处理此问题的最佳(尼斯)方法是什么?
您要使用 IN
的方式不正确,它不会那样工作。
选项:
- 将 CSV 字符串发送到 SP,然后将其拆分并创建一个临时数据集(例如表变量),然后您将使用该数据集执行
JOIN
- 动态SQL
拆分函数示例:
CREATE FUNCTION [dbo].[Split](
@String nvarchar (4000),
@Delimiter nvarchar (10)
)
RETURNS @ValueTable TABLE ([Value] nvarchar(4000), [ElementsCount] int)
BEGIN
DECLARE @nextString nvarchar(4000)
DECLARE @pos int
DECLARE @nextPos int
DECLARE @commaCheck nvarchar(1)
DECLARE @elementsCount int
SET @elementsCount = 0
--Initialize
SET @nextString = ''
SET @commaCheck = RIGHT(@string, 1)
--Check for trailing Comma, if not exists, INSERT
SET @string = @string + @delimiter
--Get position of first Comma
SET @pos = CHARINDEX(@delimiter, @string)
SET @nextPos = 1
--Loop while there is still a comma in the String of levels
WHILE (@pos <> 0)
BEGIN
SET @nextString = SUBSTRING(@string, 1, @pos - 1)
INSERT INTO @ValueTable ([Value]) VALUES (@nextString)
SET @string = SUBSTRING(@string, @pos +1, LEN(@string))
SET @nextPos = @pos
SET @pos = CHARINDEX(@delimiter, @string)
SET @elementsCount = @elementsCount + 1
END
UPDATE @ValueTable SET [ElementsCount] = @elementsCount
RETURN
END
然后你像这样使用它:
SELECT
StudentName, Age
FROM
dbo.Students
JOIN [dbo].[Split](@city, ',') Cities ON City = Cities.Value