从查询中创建IN函数,以便它可以处理多个输入

时间:2017-07-26 05:51:48

标签: c# sql winforms ms-access parameters

我不确定我是否有权表达我的意图,但我有以下TSQL查询:

SELECT *
FROM Table 
WHERE Amount_USD >= @init AND Amount_USD < @init2 

@init等于基本搜索值,@ init2等于基值加1.此代码的并置是为了读取负值(如果可用)。 (通过if else)

这是为了获取给定值的所有十进制值,包括该值。这将成为标准的长链的一部分,搜索日期,搜索ID,以及如上所述搜索给定值的所有十进制值。问题是,这只适用于一个输入,我打算让它适用于多个输入值。

现在,我遇到的问题是,如果我希望创建此查询的IN(列表)版本,以便我可以搜索任何给定值的多个十进制值,那么该怎么说呢。

例如:搜索量为100 120 130.程序从后端获取以下值:100.12,120.14,100.99,130​​,130.544 /等。

我相信可以使用OR函数完成,就像这样:

SELECT * 
FROM Table 
WHERE (Amount_USD >= @init AND Amount_USD < @init2) 
   OR (Amount_USD >= @init3 AND Amount_USD < @init4) 
   OR (Amount_USD >= @init5 AND Amount_USD < @init6)

正如你在上面看到的那样,我遇到了这样的问题,即我从没有想要避免的任何东西创建这些参数,因此IN可能更可取......现在我想到它,参数可能总是一个问题......有解决方案吗?

例如,我像我这样定义我的参数:

da.SelectCommand.Parameters.AddWithValue("@init", init);
da.SelectCommand.Parameters.AddWithValue("@init2", init2);

说,输入值计数增加到4或9.我不知道如何缩放它。

编辑:我忘了提到这是用Tsql编写的,通过windows窗口连接访问数据库。因此,许多特定于sql的函数或方法在我的情况下可能不起作用。

Edit2:上面发错了SQL查询,现在应该是正确的......

3 个答案:

答案 0 :(得分:0)

请注意Access不接受T-SQL。这意味着无法通过T-SQL(例如通过XML参数)实现可扩展的答案,其中参数的数量是未定义的。然而,有一个简单的选择。在c#中创建for循环以动态构建SQL语句。以下内容应该为您提供线索:

int[] paramArray = new int[] { 100, 102, 104, 106 };
StringBuilder sB = new StringBuilder("SELECT * FROM TABLE WHERE");
for (int i = 0; i < paramArray.Length - 1; i++)
{
    if (i > 0)
    {
        sB.Append(" OR");
    }
    sB.Append(" (Amount_USD >= " + paramArray[i].ToString() + " AND Amount_USD < " + (paramArray[i] + 1).ToString() + ")");
}
string sQL = sB.ToString();

修改

调整@Gelion建议以使用Access,您将得到:

int[] paramArray = new int[] { 100, 102, 104, 106 };
StringBuilder sB = new StringBuilder("SELECT * FROM TABLE WHERE IIF(Amount_USD < ROUND(Amount_USD),ROUND(Amount_USD)-1,ROUND(Amount_USD)) IN (");
for (int i = 0; i < paramArray.Length - 1; i++)
{
    if (i > 0)
    {
        sB.Append(", ");
    }
    sB.Append(paramArray[i].ToString());
}
string sQL = sB.ToString() + ")";
当OR超过一定数量时,

IN()通常执行得更快(希望我知道这个数字是多少!)。

答案 1 :(得分:0)

我不确定Access是否接受这个,tsql肯定会这样做:

select *
from Table t
    join (values(100),(120),(130))initVal(fromValue) 
       on initVal.fromValue <= t.Amount_USD and initVal.fromValue + 1 > t.Amount_USD

答案 2 :(得分:-1)

如果我理解正确,你可以像这样简化你的查询:

class PrivateRoute extends Component {
  render() {
    if (this.props.data.loading) {
      return <Loading />;
    } else if (this.props.data.user) {
      return (
        <div>
          <VerticalNavFixed />
          <article className="docs-content">
            <Switch>
              <Route path="/people/:id" render={(props) => {return React.cloneElement(<Person />, {user: this.props.data.user, ...props})}} />
            </Switch>
          </article>
        </div>
      );
    }
    return <Redirect to={{ pathname: '/login', state: { from: this.props.location } }} />;
  }
}


const PrivateRouteContainer = graphql(userQuery, { options: { fetchPolicy: 'network-only' } })(withRouter(PrivateRoute));

如果Acess acepts func Round有一个参数

select * FROM Table WHERE round(Amount_USD, 2, 1) in (@init1,@init3,@init5)

没有任何参数的版本,您可以在构建SQL查询期间添加新值

select * from Table WHERE case when Amount_USD<round(Amount_USD,0) then  round(Amount_USD,0)-1 else round(Amount_USD,0) end  in (@init1,@init3,@init5)

这个无参数版本不安全你必须小心并在连接之前检查数字