C# 在asp.net中查询多个可能的ID
我正在使用asp.net编写一个网站,我的任务是提供存储在SQL server中的数据的柱状图 我需要的信息存储在如下表中:C# 在asp.net中查询多个可能的ID,c#,asp.net,visual-studio-2010,sql-server-2008,C#,Asp.net,Visual Studio 2010,Sql Server 2008,我正在使用asp.net编写一个网站,我的任务是提供存储在SQL server中的数据的柱状图 我需要的信息存储在如下表中: Date | Value | Machine_ID -------------------------- 04 | 102 | 1 05 | 105 | 1 06 | 106 | 1 04 | 103 | 2 05 | 103 | 2 06 | 185 | 2 04 | 100 | 3 05 | 99 |
Date | Value | Machine_ID
--------------------------
04 | 102 | 1
05 | 105 | 1
06 | 106 | 1
04 | 103 | 2
05 | 103 | 2
06 | 185 | 2
04 | 100 | 3
05 | 99 | 3
06 | 182 | 3
我遇到的问题是,有时我们想要查看所有机器的值,通常是在一个用于查看趋势的标准化为100%的图上,就像我们在5月份总共没有生成那么多,这只是一个如下查询:
SELECT * FROM Mode_History
有时我们只想查看一台机器的历史记录,这也很容易:
SELECT * FROM Mode_History WHERE (Machine_ID = ?)
但是,我的目标是允许最终用户选择多台机器,并查看过去几天所有这些机器组合在一起的数据。如果我只是写查询,它基本上是:
SELECT * FROM Mode_History WHERE (Machine_ID = 100) OR (Machine_ID = 102)
但是,我不知道如何在asp.net中实现类似的功能
我尝试过创建数据绑定的listbox控件,并启用多个选择,然后在查询中使用它们的值作为参数,但这只返回第一个选中的项。我也试过用谷歌搜索答案,但我不太确定该如何表达这个问题
所以,我的问题是:在asp.net中实现这一点的最佳方法是什么?我主要是用C语言工作的,所以我非常希望能用C语言给出答案。不过,我对VB的理解足以将其转换 常规方法是根据您的场景更改,在代码隐藏中组装所需的SQL查询。最佳方法之一是
DECLARE @input VARCHAR(500) = '100,200'
DECLARE @UINPUT AS TABLE
(
value INT
)
INSERT INTO @UINPUT
SELECT PART FROM dbo.Split(@input,',')
-- GET THE RESULT
SELECT *
FROM Mode_History AS MH
JOIN @UINPUT AS UN
ON MH.Machine_ID = UN.value
1您需要在SQL server中将用户选择以逗号分隔的方式作为参数发送。
例:100200
2您需要使用以下内容创建存储过程
DECLARE @input VARCHAR(500) = '100,200'
DECLARE @UINPUT AS TABLE
(
value INT
)
INSERT INTO @UINPUT
SELECT PART FROM dbo.Split(@input,',')
-- GET THE RESULT
SELECT *
FROM Mode_History AS MH
JOIN @UINPUT AS UN
ON MH.Machine_ID = UN.value
3用户定义的拆分功能如下所示
CREATE FUNCTION [dbo].[Split]
(
@sString nvarchar(2048),
@cDelimiter nchar(1)
)
RETURNS @tParts TABLE ( part nvarchar(2048) )
AS
BEGIN
IF @sString IS NULL RETURN
DECLARE @iStart INT,
@iPos INT
IF SUBSTRING(@sString,1,1) = @cDelimiter
BEGIN
SET @iStart = 2
INSERT INTO @tParts
VALUES(NULL)
END
ELSE
SET @iStart = 1
WHILE 1=1
BEGIN
SET @iPos = CHARINDEX(@cDelimiter,@sString,@iStart)
IF @iPos = 0
SET @iPos = LEN(@sString)+ 1
IF @iPos - @iStart > 0
INSERT INTO @tParts
VALUES(SUBSTRING(@sString,@iStart,@iPos-@iStart))
ELSE
INSERT INTO @tParts
VALUES(NULL)
SET @iStart = @iPos+1
IF @iStart > LEN(@sString)
BREAK
end
RETURN
END
如果您不介意将查询参数化为int安全,那么有一种可能性:
SELECT * FROM Mode_History WHERE Machine_ID IN (100, 102)
这里,100、102可以作为变量追加到查询字符串中
或者,如果需要参数,请使用字符串变量:
SELECT * FROM Mode_History WHERE ',100,102,' LIKE '%,' + Machine_ID + ',%'
-- SELECT * FROM Mode_History WHERE @ParamString LIKE '%,' + Machine_ID + ',%'
这里,单个字符串“100102”可以替换为参数。它仍然将多个参数组合到一个字符串对象中,但它应该提供一定程度的安全性,以防注入攻击 我主要使用逗号分隔的数字列表,然后使用IN运算符将其附加到查询的WHERE子句中。小心任何逃逸,因为您可能无法使用参数化查询。谢谢,这就是我最后要做的。我有点担心SQL注入攻击,但老实说,这是在公司内部网上运行的,所以我认为它不会太容易受到攻击者的攻击。我会继续研究,看看我是否也能使用参数。你应该一直担心注射。就我个人而言,我觉得在某些情况下,逃跑是参数的可行替代方案,但是必须非常小心地使用它。@user2494447只要您完全控制列表,您就应该不会受到注入攻击-例如,如果您从整数列表而不是直接用户输入创建字符串,您应该可以。最好的一个。。。?这看起来是一个很长的方法来做一些事情同样,我对SQL不太熟悉,但这似乎是一个自己实现“IN”操作符的方法…这就是我最后要做的。我尝试过做类似的事情,但SQL数据源类一直检测到机器ID是int,并试图转换“102”,103'到一个int。@user2494447我很确定查询参数有一个扩展格式,您可以指定它们应该是哪种SQL或对象类型。在这种情况下,您只需要像VARCHAR255或等效的东西。ie:创建SelectParameter时,请确保设置其类型