【问题标题】:How make a custom query on the fly?如何即时进行自定义查询?
【发布时间】:2011-01-01 01:33:45
【问题描述】:

我正在使用 sqlite 在 vb.net 上的数据库中工作,该数据库托管一个画廊,我想扩展搜索属性。

这是实际的查询字符串:

"SELECT images.*
FROM images 
JOIN nodes 
ON images.id = nodes.image_id 
WHERE tag_id = (SELECT tags.id 
                FROM tags 
                WHERE tag = '" & tagname & "') 
ORDER BY images." & sort & " " & order & ""

但它只能搜索一个描述性标签(tagname)并对图像进行排序,仅此而已。

我还想过滤图像 ext (table = images.ext) 或一个或多个参数的结果...例如:

如果用户搜索“cars ext:jpg width>500”,数据库将返回所有带有“cars”标签、扩展名为 jpg 且宽度大于 500 像素的图像。

【问题讨论】:

    标签: vb.net sqlite system.data.sqlite


    【解决方案1】:

    首先,这段代码很危险。它对SQL Injection 攻击开放。您不应该只是将这样的字符串值附加到查询字符串中。相反,您应该使用参数化查询。

    关于您的具体问题,您应该检查搜索的输入,并根据输入生成查询的特定部分,并在必要时对其进行参数化。

    例如,如果您必须过滤扩展,那么您可以在包含 join 子句的变量中向扩展表添加一个连接,并在包含 where 子句的变量中的连接表上添加一个过滤器(以及作为适当的参数和参数值)。

    然后,最后,将查询的各个部分(连同查询参数)连接在一起并执行它。

    【讨论】:

    • 这段代码是在本地数据库中使用的,而不是在sql server中。它使用 sqlite 并且用户从他的计算机而不是互联网上加载图像。
    • @Sein Kraft:代码的使用位置无关紧要,如果标记名、排序或顺序参数的任何部分依赖于用户输入(即使在派生意义上),那么您就是主题到 SQL 注入。
    • 连接查询字符串仍然是一个坏习惯。不要这样做,尤其是示例代码。
    【解决方案2】:

    如果我正确理解了这个问题,您只想构建一个查询字符串。你有没有尝试过这样的事情?

    SQLcommand.CommandText = "SELECT images.* FROM images JOIN nodes ON images.id = nodes.image_id WHERE tag_id = (SELECT tags.id FROM tags WHERE tag = '" & tagname & "') AND images.Ext = '" & ext & "' AND width > " & width & " ORDER BY images." & 排序 & " " & 排序 & ""

    【讨论】:

    • 这与原始问题一样,使代码容易受到 SQL 注入的影响
    • 当然容易受到Sql Injection的影响。 (a) 安全性不是问题的一部分,并且 (b) 操作人员已经表示它是本地应用程序
    • @bglenn:作为旁注,您可以使用 101010 按钮来格式化您的代码(或缩进 4 个空格)。
    • 感谢桑德。我是新来的,一定会用的。
    • @bglenn:即使它是一个本地应用程序,如果用户有意或无意地在其中输入了一些包含引号的文本,那么应用程序要么会做一些奇怪和意想不到的事情,要么更多可能会失败并显示令人困惑的错误消息。没有充分的理由不以正确的方式使用参数。
    【解决方案3】:

    首先,如果该输入来自用户,请不要像这样连接字符串,因为它对SQL Injection很有效

    使用 SQL 参数是一种避免注入的方法:

    command.CommandText = "SELECT images.* " &_
                          "FROM images " &_
                          "JOIN nodes " &_
                          "ON images.id = nodes.image_id " &_
                          "WHERE tag_id = (SELECT tags.id " &_
                                          "FROM tags " &_
                                          "WHERE tag = @tag)"
    

    您可以将其扩展为:

    command.CommandText = "SELECT images.* " &_
                          "FROM images " &_
                          "JOIN nodes " &_
                          "ON images.id = nodes.image_id " &_
                          "WHERE tag_id = (SELECT tags.id " &_
                                          "FROM tags " &_
                                          "WHERE tag = @tag)"
    
    command.Parameters.AddWithValue("@tag", searchTag)
    
    
    If Not String.IsNullOrEmpty(searchExt) Then
        command.CommandText = command.CommandText & " AND images.ext = @imageExt"
        command.Parameters.AddWithValue("@imageExt", searchExt)
    EndIf
    
    If Not String.IsNullOrEmpty(searchWidth) Then
        command.CommandText = command.CommandText & " AND images.width > @imageWidth"
        command.Parameters.AddWithValue("@imageWidth", searchWidth)
    EndIf
    

    【讨论】:

    • 如果用户不输入文件分机会发生什么?我的意思是如果 searchExt 为 null 或为空?
    • 它可能不适合,但你会明白的,谢谢
    【解决方案4】:

    单独构建 WHERE 子句,并将其添加到您的查询中。

    where="1"
    if tagname<>"" then where=where & " AND tag='" & tagname & "'"
    ...
    "SELECT images.*
    FROM images 
    JOIN nodes 
    ON images.id = nodes.image_id 
    WHERE tag_id = (SELECT tags.id 
                    FROM tags 
                    WHERE " & where & " ) 
    ORDER BY images." & sort & " " & order & ""
    

    【讨论】:

      猜你喜欢
      • 2010-11-01
      • 1970-01-01
      • 2014-07-10
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      • 2011-07-31
      • 1970-01-01
      • 2017-07-27
      相关资源
      最近更新 更多