从字符串中删除最后的“OR”

时间:2011-06-20 11:22:09

标签: sql vb.net string

我正在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)没问题,除了它不处理空字符串。毕竟,我不知道我的数组中有多少元素。

9 个答案:

答案 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()。