【问题标题】:How do I make sure an input SQL Statement has valid column names using Java?如何使用 Java 确保输入 SQL 语句具有有效的列名?
【发布时间】:2021-07-16 22:56:04
【问题描述】:

我正在编写将 SQL 语句作为字符串文件读取的 Java 程序,但是程序需要验证 SQL 语句是否具有有效的列名。有 2 个文件保存列名,它们也存储在字符串中。我正在努力弄清楚如何将两个文件与一个 SQL 语句字符串进行比较的逻辑。

以下是用户可以输入的可能的 SQL 语句示例: SELECT * JobHost where class_id ='MAA';

我的第一种方法是通过 select & from 拆分文件,然后逐行读取并将其存储为数组列表。然后将数组列表与字符串文件列名进行比较,或者将列名放在数组列表中。

最好的方法是什么?

【问题讨论】:

  • 如果您有一个包含列名的 SQL 语句,那么您将不得不解析 SQL 语句以识别列名。但我不明白你为什么要这样做。您打算处理哪些 SQL 语句?它们有多复杂?
  • 如果您关心列名,我建议您使用列名,而不是*。您能否举例说明您正在做什么以便我们更容易地提供帮助?
  • I am writing Java program that reads in SQL Statement as string file ... 这是什么意思?您正在阅读 CSV 文件吗? Here is an example of a possible SQL Statement the user can input: SELECT * JobHost where class_id ='MAA'; ... 不允许用户输入任意表字段名称。强制用户从下拉组合框中的列表中选择这些表字段名称。这样就没有什么可以确认的了。您可以轻松获取表格元数据以获取表格字段名称。

标签: java sql validation


【解决方案1】:

不可能。

SQL 是一种复杂的语言,实现您想要的唯一方法是编写一个完整的 SQL 解析器,这是一个涉及非常熟悉非常复杂的库(解析器库)的项目。专家需要数周时间才能建立起来。

您的问题也做出了您无法做出的假设。这些是有效 SQL 的示例,它们不会在列上进行选择,但其中一些涉及列:

  • SELECT 1;
  • SELECT colname > 1 FROM foo;
  • SELECT x."ALIAS" FROM (SELECT colname AS alias FROM table) x;
  • SELECT EXTRACT(YEAR from colname) FROM table;

只要看看第三个,就知道你没有机会了。

然后查看第 4 条,并意识到 如果 你想在将 SQL 扔到数据库之前验证某个字符串是否包含健全的 SQL 的路径比你想象的要复杂得多认为是:仍然可以检查 colname,但您不应停止检查这是否是有效列,您还应该检查该列是否属于 EXTRACT(YEAR from) 操作中支持的类型。

然后意识到几乎每个 SQL 引擎都支持不同的 SQL 语法和扩展,所以你不能只编写一个 SQL 解析器,你必须为 psql 编写一个,为 mysql 编写一个,为 mssql 编写一个,等等。

绝望的情况。

那么,该怎么办?

只需运行这些东西:将它扔到数据库中。如果它无效,数据库会告诉你SQLException。您可以使用sqlEx.getSQLState() 从中获取特定的数据库错误。不幸的是,该字符串完全依赖于底层 SQL 引擎,但幸运的是,大多数 SQL 引擎都提供了高度特定的机器可解析信息。例如,如果那里有 gobbledygook,psql 会给你42601。如果你想区分,写一个你想知道的特定问题的 SQL 语句(例如使用不存在的 colname),运行它,打印 SQLState。现在您知道要寻找什么了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    相关资源
    最近更新 更多