我正在运行以下查询
cmd = new SqlCommand("SELECT * FROM addresses WHERE identifier NOT IN(@notIn)", _connector.getMsConnection());
当我查看值notIn并复制此查询时,我在数据库中得到一个空结果(我期待)。但是,当我运行此代码时,我得到6个结果。 字符串 notIN的内容例如是
string notIn = "'201619011124027899693E8M2S3WOCKT9G6KHE11' ,'201619011124027899693E8M2S3WOCKT9G6KHE12'"
与
结合SELECT *
FROM addresses
WHERE identifier NOT IN(@notIn)
应该创建
SELECT *
FROM addresses
WHERE identifier NOT IN ('201619011124027899693E8M2S3WOCKT9G6KHE11',
'201619011124027899693E8M2S3WOCKT9G6KHE12' )
按预期运行。
答案 0 :(得分:0)
它应该是这样的:
cmd = new SqlCommand(string.Format("SELECT * FROM addresses WHERE identifier NOT IN({0})", notIn), _connector.getMsConnection());
这样,notIn的值将与字符串查询连接。
答案 1 :(得分:0)
与其他答案所说的相反,连接字符串以构建SQL是一个坏主意,尤其是,因为输入值是字符串。你打开了SQL注入攻击。
您应该为列表中的每个项目生成多个参数。
例如,如果您有输入输入:
var notIn = new[] { "A1", "B2", "C3" }
你想要像
这样的东西for(var i = 0; i < notIn.Length; i++)
command.AddParamWithValue("p"+i, notIn);
然后你可以用连接构建SQL(注意我们不是在这里连接输入)
var sql = "SELECT * FROM addresses WHERE identifier NOT IN(" + string.Join(",", notIn.Select(i,v) => { "@p" + i; }) + ")";
然后看起来像:
SELECT * FROM addresses WHERE identifier NOT IN (@p0,@p1,@p2)
或者,您可以将值转储到临时表中并进行连接。
请注意,上面是伪代码,可能无法编译 verbatim ,但应该为您提供有关如何处理的正确信息。
答案 2 :(得分:-1)
这是因为,您将@notIn作为整个字符串传递,这意味着,SQL服务器将其视为:
SELECT * FROM addresses WHERE identifier NOT IN('''201619011124027899693E8M2S3WOCKT9G6KHE11'',''201619011124027899693E8M2S3WOCKT9G6KHE12''')
所以你得到空的结果
尝试更改&#34;而不是&#34; to where子句并使用C#生成where:
string selectStatement = "SELECT * FROM addresses WHERE";
selectStatement += " identifier != '201619011124027899693E8M2S3WOCKT9G6KHE11' and identifier != '201619011124027899693E8M2S3WOCKT9G6KHE12'";
或者,如果您真的想使用参数化SQL,请尝试在存储过程中执行此操作。