2011-08-18 94 views
1

我有一个关于SQL的问题。我有以下SQL语句:动态构建SQL语句中的WHERE子句

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设置一个字符串,该字符串可以在我的程序中分配到我想要搜索的列吗?

谢谢

+1

您使用的数据库是? –

+0

您是否有特定的数据库(即Oracle,MS SQL Server,mySQL)?您通常需要使用动态SQL来实现这样的功能,这会因具体数据库而异。不过,我将在下面包含一个非动态SQL方法。 –

+0

您需要的功能称为“动态SQL” - 它可能会或可能不会在您的平台上提供。什么是你的数据库引擎? –

回答

2

该列不能变量,但列的值可以。解析器需要知道绑定到什么。

如果您详细说明您正在尝试解决什么问题以及您使用的是哪个平台,则可以提供更完整的答案。

+0

我有30个sql语句,它们只是按他们在(SOMETHING_SHOULD_BE_HERE)中搜索的列进行推迟。我可以将列名分配给在程序中随机分配的变量列名,而不是将此sql语句写入30次。我想你的答案是否定的(列不能变)。他们有任何其他方式来做到这一点? – hhhhhhh

+0

看看@Tom H的答案。 – Yuck

3

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

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

1

您可以在代码中使用不同的SQL查询,并根据大小写使用每个查询。

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

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 
} 
+1

根据“colName”来自哪里,您可能会在这里打开自己的SQL注入攻击。 –

+0

非常感谢! – hhhhhhh

+0

@汤姆,是的,你说得对。对于那种情况,我们可以在jdbc中使用动态sql, 'String sql =“select * form?”; ps = c.prepareStatement(sql); ps.setString(1,colName); rs = ps.getResultSet();' – Ivan

0

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

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

如果您拥有少量的可能性,可以使用CASE来解决您的问题。

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的注意事项。

0

你的问题还不清楚。

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

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

  1. 当你的查询将返回一个且只有一个行

    ,那么你必须考虑EXECUTE IMMEDIATE语句(在TSQL sp_executesql的沿:http://msdn.microsoft.com/en-us/library/ms188001.aspx;或者在PL/SQL的使用条款: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. 当你的查询可以返回多行

    ,那么你必须要考虑技术,如用大头EXECUTE IMMEDIATE语句收进子句或OPEN-FOR,FETCH和CLOSE语句(显式游标在PL/SQL: http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/dynamic.htm

请注意,除了在某些特定情况下,如IF-THEN-ELSE和CASE语句最常规的技术应该(连同一个好的算法)首选。此外,他们与几乎所有的RDBMS一起工作。