【问题标题】:Using table columns in prepared statement parameter在准备好的语句参数中使用表列
【发布时间】:2014-08-03 08:16:33
【问题描述】:

我的页面有一个下拉列表,让用户可以选择任何搜索类别,如标题、描述等。所以我有这个SQL语句:

select * from table where "selected value from dropdown list" = "searchform"

我想将它传递给准备好的语句,如下所示:

select * from table where ? = ?

由于我的 select 语句形式相同,只有 where 子句中的列不同,有没有办法做到这一点,而无需为每一列手动创建 select 语句?

【问题讨论】:

    标签: sql sql-server jdbc


    【解决方案1】:

    对,就是叫动态sql。

    DECLARE @sql AS VARCHAR(MAX)
    SET @sql = 'select * from table where ' + @column + ' = ''' + @value + ''''
    EXEC(@sql)
    

    您必须检查列是否为数字类型。 您还应该小心 sql 注入。我的例子是一个非常简单的例子,所以你必须自己做检查。

    例如使用QUOTENAME 会很有用:

    DECLARE @sql AS VARCHAR(MAX)
    SET @sql = 'select * from table where ' + QUOTENAME(@column) + ' = ''' + @value + ''''
    EXEC(@sql)
    

    上面的例子只是TSQL。在你准备好的陈述中,我认为你可以有以下内容:

    PreparedStatement pstmt = con.prepareStatement("
        DECLARE @sql AS VARCHAR(MAX)
        SET @sql = 'select * from table where ' + QUOTENAME(?) + ' = ? '
        EXEC(@sql)
    ");
    pstm.setString(1,columnName);
    pstm.setString(2,filterValue);
    

    不幸的是我不熟悉 JAVA,所以我没有测试过这个。不过我觉得值得一试。

    上面的@sql 变量会产生如下语句:

    select * from table where [columnname] = filtervalue
    

    columnname 用括号括起来将有助于防止 SQL 注入。

    【讨论】:

    • 我应该把这个放在准备好的语句中吗?
    • 检查我的编辑。我不熟悉java,所以这可能是错误的。我刚刚在有关如何使用准备好的语句的文档中发现了这一点。另一个问题是你不知道在第二个参数中传递什么,但我想你可以有一个开关或其他东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多