我正在VB.net中构建一个SQL查询,并编写了一个动态执行它的例程。
我想在where子句中包含数组(大小未知)中的每个项目,如下:
Dim person(10) as String
Dim strSQL, strWhereClause as String
person(0) = "John"
person(1) = "Steve"
'...
For i = 0 To UBound(menuNames)
strWhereClause &= "[name] = '" & person(i) & "' OR "
Next
strSQL= "SELECT * FROM [customers] WHERE " & strWhereClause
这里的问题是最后有一个额外的" OR "
。有一种巧妙的方法可以删除它吗?或者也许是一起解决问题的更好方法。 (我认为string.join在这种情况下不起作用,因为数组项之前和之后都有文本。)
编辑:手动删除最后三个字符如下:strWhereClause = Left(strWhereClause, strWhereClause.Length - 3)
没问题,除了它不处理空字符串。毕竟,我不知道我的数组中有多少元素。
答案 0 :(得分:9)
你不应该这样做,即使你100%确定数组中存储的内容仍然是一个坏习惯。相反,你应该熟悉parameterized queries。
未经过编译测试:
var sb = new StringBuilder();
sb.Append("SELECT * FROM [customers] WHERE ");
for (int i = 0; i < person.Length; ++i)
{
var param = string.Format("NAME{0}", i);
sb.Append(string.Format("[NAME] = @{0}{1}", param, i < person.Length - 1 ? " OR " : string.Empty));
command.Parameters.AddWithValue(param, person[i]);
}
var sql = sb.ToString();
假设您的SqlCommand是command
。
抱歉C#但我的VB太生锈了,我希望你明白这一点。 ;)
答案 1 :(得分:2)
在我看来,这取决于你的目标:
1.最少的代码行/最容易阅读的代码
2.最高效率
实际上,Option2仅在字符串变得很长或者你要重建字符串很多次时才有意义。
对于简短的代码,我会像你一样构建字符串,然后删除你不需要的位......
Dim person(10) as String
Dim strSQL, strWhereClause as String
person(0) = "John"
person(1) = "Steve"
i = -1
For i = 0 To UBound(menuNames)
strWhereClause &= " OR [name] = '" & person(i) & "'"
Next
IF (i >= 0) THEN
strWhereClause = RIGHT(strWhereClause, LEN(strWhereClause) - 3)
strSQL= "SELECT * FROM [customers] WHERE " & strWhereClause
END IF
这里有两点低效率......
1.每次连接字符串,创建一个新字符串涉及大量重新分配内存和复制字符串
2.修剪最后三个字符计算字符串的整个长度,然后将几乎整个字符串的长度复制到新分配的内存位置
如果你确实想要更高效率,可以避免以上的低效率......
Dim person(10) as String
Dim strSQL, strWhereClause as String
person(0) = "John"
person(1) = "Steve"
If (UBound(menuItems) >= 0) THEN
strWhereClause &= " [name] = '" & person(0) & "'"
If (UBound(menuItems) >= 1) THEN
For i = 1 To UBound(menuNames)
strWhereClause &= " OR [name] = '" & person(i) & "'"
Next
END IF
strSQL= "SELECT * FROM [customers] WHERE" & strWhereClause
END IF
(这会将检查放在循环之外,你真的不想每次检查都检查一次。)
答案 2 :(得分:2)
如果您也能使用LINQ,则使用String.Join将适用于此。我相信下面的内容应该适用于dotNet 3.5 +
Dim person(2) As String
Dim out As String
person(0) = "Test 1"
person(1) = "Test 2"
person(2) = "Test 3"
out = String.Join(" Or ", person.Select(Function(n) String.Format("[name] = '{0}'", n)).ToArray)
这将产生以下结果:
[name] = 'Test 1' Or [name] = 'Test 2' Or [name] = 'Test 3'
只需将'out'附加到SQL语句
即可答案 3 :(得分:1)
通过一些额外的逻辑,你不需要更换字符串:
Dim person(10) as String
Dim strSQL, strWhereClause as String
person(0) = "John"
person(1) = "Steve"
'...
For i = 0 To UBound(menuNames)
If i = 0 Then
strWhereClause &= "[name] = '" & person(i) & "'"
Else
strWhereClause &= " OR [name] = '" & person(i) & "'"
EndIf
Next
strSQL= "SELECT * FROM [customers] WHERE " & strWhereClause
答案 4 :(得分:1)
以下是使用System.Text.StringBuilder
的解决方案:
Dim person(1) As String
Dim strSQL, strWhereClause As String
person(0) = "John"
person(1) = "Steve"
'...
Dim menuNames(person.Length - 1) As String
Dim Sb As New System.Text.StringBuilder
Dim i As Int32
Sb.Append("SELECT * FROM [customers] WHERE ")
For i = 0 To UBound(menuNames) - 1
'strWhereClause &= "[name] = '" & person(i) & "' OR "
Sb.Append("[name] = '")
Sb.Append(person(i))
Sb.Append("' OR ")
Next
Sb.Append("[name] = '")
Sb.Append(person(menuNames.Length - 1))
Sb.Append("'")
strSQL = Sb.ToString
注意:此解决方案在Visual Studio 2010中测试正常。
答案 5 :(得分:0)
将此行添加到结尾:
strWhereClause = strWhereClause.replaceAll(" OR $", "");
哎呀 - 那是java。希望你能用它:)
答案 6 :(得分:0)
当然,你可以在sqlStr赋值之前删除strWhereClause的最后三个字符吗?
类似的东西:
Next
strWhereClause = Mid(strWhereClause, 0, Len(strWhereClause) - 3)
strSQL= "SELECT * FROM [customers] WHERE " & strWhereClause
当有0个人时,您还需要处理异常。
答案 7 :(得分:0)
您可以使用Substring
功能。
strWhereClause = strWhereClause.Substring(0, strWhereClause.Length - 3);
上面显示的示例使用C#。
答案 8 :(得分:0)
不要在结束之前构建SQL字符串。将每个“OR”条件放在List&lt; String&gt;中然后使用“OR”执行String.Join()。