C# 无法在asp.net C中创建动态sql查询
我越来越累了 将varchar值“4643415864”转换为数据类型int时,转换失败 我有一个接受数字和逗号的文本框。我需要使用类似于4643415864语法的emp_num创建查询 codebehind生成的查询如下,在sql server中手动运行良好:C# 无法在asp.net C中创建动态sql查询,c#,asp.net,sql-server,C#,Asp.net,Sql Server,我越来越累了 将varchar值“4643415864”转换为数据类型int时,转换失败 我有一个接受数字和逗号的文本框。我需要使用类似于4643415864语法的emp_num创建查询 codebehind生成的查询如下,在sql server中手动运行良好: SELECT * -- column names FROM [DBO].[tablename] LPR WHERE LPR.[EMPLOYEE_NUMBER] in (46434,15864) 代码: 表: 基本上,错误是您
SELECT * -- column names
FROM [DBO].[tablename] LPR
WHERE LPR.[EMPLOYEE_NUMBER] in (46434,15864)
代码:
表:
基本上,错误是您的变量@empnumber是varchar,LPR。[EMPLOYEE_NUMBER]是整数 您可以将文本框的值附加到查询中
编辑:正如其他人所建议的,这很容易导致SQL注入。Marc Guillot和Nino的解决方案更好。基本上,错误是您的变量@empnumber是varchar,LPR。[EMPLOYEE_NUMBER]是整数 您可以将文本框的值附加到查询中
编辑:正如其他人所建议的,这很容易导致SQL注入。Marc Guillot和Nino解决方案更好。您需要一个拆分函数来从字符串创建列表。您可以创建运行此脚本的函数一次:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fnSplitString]
(
@string NVARCHAR(MAX),
@delimiter CHAR(1)
)
RETURNS @output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
set @delimiter = coalesce(@delimiter, dbo.cSeparador());
DECLARE @start INT, @end INT
SELECT @start = 1, @end = CHARINDEX(@delimiter, @string)
WHILE @start < LEN(@string) + 1 BEGIN
IF @end = 0
SET @end = LEN(@string) + 1
INSERT INTO @output (splitdata)
VALUES(SUBSTRING(@string, @start, @end - @start))
SET @start = @end + 1
SET @end = CHARINDEX(@delimiter, @string, @start)
END
RETURN
END
您可以完全按照调用原始代码的方式从C中调用它。您需要一个拆分函数来从字符串创建列表。您可以创建运行此脚本的函数一次:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fnSplitString]
(
@string NVARCHAR(MAX),
@delimiter CHAR(1)
)
RETURNS @output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
set @delimiter = coalesce(@delimiter, dbo.cSeparador());
DECLARE @start INT, @end INT
SELECT @start = 1, @end = CHARINDEX(@delimiter, @string)
WHILE @start < LEN(@string) + 1 BEGIN
IF @end = 0
SET @end = LEN(@string) + 1
INSERT INTO @output (splitdata)
VALUES(SUBSTRING(@string, @start, @end - @start))
SET @start = @end + 1
SET @end = CHARINDEX(@delimiter, @string, @start)
END
RETURN
END
您可以完全按照调用原始代码的方式从C中调用它。您必须对每个值进行参数化。这样,您就可以动态创建查询,但不容易使用SQL注入 以下是代码:
//where IN part of your query
string inClause = "and LPR.[EMPLOYEE_NUMBER] in ({0})";
// string arrays for values and variables of your query
string[] paramValues = txtEmpNum.Text.Trim().Split(',');
string[] paramVars = paramValues.Select((s, i) => "@empNo" + i.ToString()).ToArray();
//create query, ie. and LPR.[EMPLOYEE_NUMBER] in (@empNo0, @empNo1...)
inClause = string.Format(inClause, string.Join(", ", paramVars));
//add vars and values to command
for (int i = 0; i < paramVars.Length; i++)
{
cmd.Parameters.Add(paramVars[i], SqlDbType.Int).Value = paramValues[i];
}
您必须将每个值参数化。这样,您就可以动态创建查询,但不容易使用SQL注入 以下是代码:
//where IN part of your query
string inClause = "and LPR.[EMPLOYEE_NUMBER] in ({0})";
// string arrays for values and variables of your query
string[] paramValues = txtEmpNum.Text.Trim().Split(',');
string[] paramVars = paramValues.Select((s, i) => "@empNo" + i.ToString()).ToArray();
//create query, ie. and LPR.[EMPLOYEE_NUMBER] in (@empNo0, @empNo1...)
inClause = string.Format(inClause, string.Join(", ", paramVars));
//add vars and values to command
for (int i = 0; i < paramVars.Length; i++)
{
cmd.Parameters.Add(paramVars[i], SqlDbType.Int).Value = paramValues[i];
}
您必须删除“,”但从何处,输入字段?您的in语句与Dynamic错误您必须删除“,”但从何处,输入字段?您的in语句与Dynamic错误是否可以拆分文本框的输入,然后将其作为两个独立的int参数添加?这样它就不会受到SQL注入的攻击。是的,但是两个参数就足够了吗?。用户是否会尝试检查三个或四个代码?那么,将其拆分,然后遍历所有部分。有点复杂,但至少它会导致更安全的代码。是的,您可以使用分割函数,并在您的选择上使用它。我将编辑我的答案以显示它。难道不可能拆分文本框的输入,然后将其添加为两个独立的int参数吗?这样它就不会受到SQL注入的攻击。是的,但是两个参数就足够了吗?。用户是否会尝试检查三个或四个代码?那么,将其拆分,然后遍历所有部分。有点复杂,但至少它会导致更安全的代码。是的,您可以使用分割函数,并在您的选择上使用它。我将编辑我的答案以显示它。完美的解决方案!非常感谢,尼诺。只是好奇为什么它不起作用。我之所以这样问,是因为stringbuilder中生成的查询在sql server编辑器窗口上运行良好,但不是在这里?通过添加带参数的参数。添加,因为它的类型为VarChar,所以您的参数将包含在单个qoutes中,并在'4643415864'中成为LPR。[员工编号]。完美的解决方案!非常感谢,尼诺。只是好奇为什么它不起作用。我之所以这样问,是因为在stringbuilder中生成的查询在sql server编辑器窗口上运行良好,但在这里没有运行?通过使用参数添加参数。添加,由于其类型为VarChar,您的参数将包含在单个qoutes中,并在'4643415864'中成为LPR。[员工编号]