在SQL语句中动态构建WHERE子句

时间:2011-08-18 14:20:28

标签: sql

我对SQL有疑问。我有以下SQL语句:

SELECT id, First, Last, E_Mail, Notes
FROM mytable
WHERE SOMETHING_SHOULD_BE_HERE IS NOT NULL;

我知道SOMETHING_SHOULD_BE_HERE应该是我表中的一个列(属性)。他们是一种方法,我可以把一个变量,可以参考我试图访问的列?在我的情况下,他们是30列。我可以在SOMETHING_SHOULD_BE_HERE中找到一个字符串,可以在我的程序中分配到我想要搜索的列吗?

由于

7 个答案:

答案 0 :(得分:3)

没有。 SQL中的变量可以引用数据,但不能引用对象名称(列,函数或其他数据库对象)。

如果要构建SQL查询,则需要使用字符串操作来构建查询。

答案 1 :(得分:2)

列不能是变量,但列的值可以。解析器需要知道要绑定的内容。

如果您详细说明您要解决的问题以及您正在使用的平台,那么可以获得更完整的答案。

答案 2 :(得分:1)

您可以在代码中使用不同的SQL查询,并根据具体情况使用每个查询。

另一种方法是根据您想要的字段动态生成查询。

答案 3 :(得分:1)

如果没有动态SQL,这可能是您最好的选择:

SELECT
    id, first, last, email, notes
FROM
    My_Table
WHERE
    CASE @column_name_variable
        WHEN 'column_1' THEN column_1
        WHEN 'column_2' THEN column_2
        ...
        ELSE 'not null'
    END IS NOT NULL

数据类型转换可能存在一些问题,因此您可能需要将所有列显式地转换为一种数据类型(VARCHAR可能是最好的选择)。此外,这个查询的性能很可能会很糟糕。在考虑实施这样的事情之前,我会彻底测试它。

我在评论中提到过这一点,但为了完整起见,我也将它放在这里......你也可以通过动态SQL实现这一点,但是你如何做到这一点将取决于你的数据库服务器(MS SQL Server,Oracle) ,mySQL等)并且通常有一些使用动态SQL的警告。

答案 4 :(得分:0)

在JDBC程序中,是的,select语句可以像字符串操作一样组成。

for(String colName: colList)
{
String sql="Select id, First, Last, E_Mail, Notes From mytable where "+colName+" IS NOT NULL";
//execute the sql statement
 }

答案 5 :(得分:0)

这取决于你如何找出SOMETHING_SHOULD_BE_HERE的价值。

如果您在Oracle PLS / SQL环境中,则可以使用动态SQL构建WHERE子句,然后使用EXECUTE IMMEDIATE来执行它。

如果您有一小部分可能性,可以使用CASE来解决您的问题。

答案 6 :(得分:0)

你的问题不清楚。

但是我很确定你所想的是所谓的动态SQL(和相关的)。 “动态SQL”允许您在运行时动态构建和提交查询。但是,您的RDBMS可能不存在此类功能。

有几种方法可以做到这一点。

  1. 当您的查询返回一行而且只返回一行时

    然后你必须考虑EXECUTE IMMEDIATE语句(以及tSQL中的sp_executesql:http://msdn.microsoft.com/en-us/library/ms188001.aspx;或者PL / SQL中的USING子句:http://docs.oracle.com/cd/B14117_01/appdev.101/b10807/13_elems017.htm来指定输入/输出绑定参数列表)和/或PREPARED语句(http://rpbouman.blogspot.fr/2005/11/mysql-5-prepared-statement-syntax-and.html)。

  2. 当您的查询可以返回多行时

    然后你必须考虑诸如带有BULK COLLECT INTO子句的EXECUTE IMMEDIATE语句或OPEN-FOR,FETCH和CLOSE语句(PL / SQL中的显式游标)之类的技术: http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/dynamic.htm

  3. 请注意,除了某些特殊情况外,大多数常规技术(如IF-THEN-ELSE和CASE语句)应该是首选(以及一个好的算法)。此外,它们几乎适用于所有RDBMS。