1

我正在使用 an 分页数据,ObjectDataSource并且我有以下方法:

public int GetNumberOfArticles(string employeeIds)
{
    System.Data.DataTable dataTable;
    System.Data.SqlClient.SqlDataAdapter dataAdapter;
    System.Data.SqlClient.SqlCommand command;

    int numberOfArticles = 0;

    command = new System.Data.SqlClient.SqlCommand();
    command.Connection = Classes.Database.SQLServer.SqlConnection;

    command.CommandText = @"SELECT COUNT(*)
                            FROM 
                                  [Articles]
                            WHERE 
                                  [Articles].[EmployeeID] IN (@EmployeeIds)";

    command.Parameters.AddWithValue("@EmployeeIds", employeeIds);
    numberOfArticles = (int)command.ExecuteScalar();
    return numberOfArticles;
}

EmployeeID是一个整数,因此,我放入的任何内容employeeIds都将转换为整数。但是,因为我使用的是IN关键字,很明显我想employeeIds用逗号分隔的 id 列表替换:

1, 2, 3

但是当我更换线路时:

command.Parameters.AddWithValue("@EmployeeIds", employeeIds);

有类似的东西:

command.Parameters.AddWithValue("@EmployeeIds", "1, 2, 3");

我收到一个异常,因为我提供了一个字符串,而EmployeeIds它是一个整数。那么,我将如何去做呢?

谢谢。

编辑:

从回复中,我了解到这必须手动完成,但是包含此方法的类将由ObjectDataSource. 那么我怎样才能提供employeeIds运行时的值呢?

4

4 回答 4

2

这样做的唯一方法是在查询中手动解析字符串并将值插入内存表,然后在查询中加入内存表,而不是使用IN子句。

例如,CodeProject 上的这个页面展示了这个功能:

IF EXISTS(SELECT * FROM sysobjects WHERE ID = OBJECT_ID(’UF_CSVToTable’))
 DROP FUNCTION UF_CSVToTable
GO

CREATE FUNCTION UF_CSVToTable
(
 @psCSString VARCHAR(8000)
)
RETURNS @otTemp TABLE(sID VARCHAR(20))
AS
BEGIN
 DECLARE @sTemp VARCHAR(10)

 WHILE LEN(@psCSString) > 0
 BEGIN
  SET @sTemp = LEFT(@psCSString, ISNULL(NULLIF(CHARINDEX(',', @psCSString) - 1, -1),
                    LEN(@psCSString)))
  SET @psCSString = SUBSTRING(@psCSString,ISNULL(NULLIF(CHARINDEX(',', @psCSString), 0),
                               LEN(@psCSString)) + 1, LEN(@psCSString))
  INSERT INTO @otTemp VALUES (@sTemp)
 END

RETURN
END
Go

然后你可以像这样使用它:

SELECT                          
    COUNT(*)
FROM 
    [Articles]

JOIN dbo.UF_CSVToTable(@EmployeeIds) ids on ids.sID = [Articles].[EmployeeID]

但最终,这通常不是一个好习惯。但是,如果有必要,那么这种方法应该以一种非常简单的方式提供给您。

于 2009-04-12T13:47:50.327 回答
2

您可以使用字符串连接创建这样的 SQL 语句:

“选择...输入(@id1,@id2,@id3)”

接着:

command.Parameters.AddWithValue("@id1", employeeIds[0]); command.Parameters.AddWithValue("@id2", employeeIds[1]); command.Parameters.AddWithValue("@id3", employeeIds[2]);

(当然使用 for 循环)。

这样,您仍然可以使用参数插入值。

于 2009-04-12T14:21:02.400 回答
1

此问题类似,您需要在运行时为每个值添加一个参数:

public int GetNumberOfArticles(string employeeIds)
{
    System.Data.DataTable dataTable;
    System.Data.SqlClient.SqlDataAdapter dataAdapter;
    System.Data.SqlClient.SqlCommand command;

    int numberOfArticles = 0;

    command = new System.Data.SqlClient.SqlCommand();
    command.Connection = Classes.Database.SQLServer.SqlConnection;

    string params = string.Join(",", employeeIds.Select((e, i)=> "@employeeId" + i.ToString()).ToArray());
    command.CommandText = @"SELECT                          
                               COUNT(*)
                            FROM 
                               [Articles]
                            WHERE 
                               [Articles].[EmployeeID] IN (" + params + ")";

    for (int i = 0; i < employeeIds.Length; i++) {
       command.Parameters.AddWithValue("@employeeId" + i.ToString(), employeeIds[i]);
    }

    numberOfArticles = (int)command.ExecuteScalar();

    return numberOfArticles;
}
于 2009-04-12T14:53:53.010 回答
0

参数是一个不同的值,不能像您尝试那样用于动态创建 SQL 语句。您将需要使用字符串连接创建 SQL 语句,这可能很简单:

command.CommandText = @"SELECT COUNT(*) FROM [Articles] " +
    "WHERE [Articles].[EmployeeID] IN (" + employeeIds + ")";

但是,如果它来自用户输入,则需要对 employeeIds 字符串进行清理,以避免 SQL 注入漏洞。您可以通过将字符串拆分为数组并解析每个元素以检查它是否为 int 来做到这一点。如果它通过,那么您可以在连接之前将数组重新加入字符串。

于 2009-04-12T14:00:03.230 回答