简体   繁体   English

如何使用 Java 确保输入 SQL 语句具有有效的列名?

[英]How do I make sure an input SQL Statement has valid column names using Java?

I am writing Java program that reads in SQL Statement as string file, however the programs needs to validate that the SQL statement has valid column names.我正在编写将 SQL 语句作为字符串文件读取的 Java 程序,但是程序需要验证 SQL 语句是否具有有效的列名。 There are 2 files that hold the column names and they are stored in a string as well.有 2 个文件保存列名,它们也存储在一个字符串中。 I am struggling with figuring out the logic on how to compare both files to the one SQL statement string.我正在努力弄清楚如何将两个文件与一个 SQL 语句字符串进行比较的逻辑。

Here is an example of a possible SQL Statement the user can input: SELECT * JobHost where class_id ='MAA';以下是用户可以输入的可能 SQL 语句的示例: SELECT * JobHost where class_id ='MAA';

My first approach is to split the file by select & from then read it line by line and store it an array list.我的第一种方法是通过 select & from 拆分文件,然后逐行读取并将其存储为数组列表。 And then compare the array list to the string file column names or maybe place the column names in an array list.然后将数组列表与字符串文件列名进行比较,或者将列名放在数组列表中。

What is the best way to go about this?解决这个问题的最佳方法是什么?

Impossible.不可能的。

SQL is a complex language and the only way to do what you want is to write a full blown SQL parser which is a project that involves being quite familiar with very complicated libraries (parser libraries). SQL 是一种复杂的语言,做你想做的唯一方法是编写一个完整的 SQL 解析器,这是一个非常熟悉非常复杂的库(解析器库)的项目。 An expert would need weeks to build that up.专家需要数周时间才能建立起来。

Your question also makes assumptions you can't make.您的问题也做出了您无法做出的假设。 These are examples of valid SQL, and they don't select on columns, but columns are involved in some of these:这些是有效 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;

Just look at that third one, and realize that you stand no chance.只要看看第三个,就会意识到你没有机会。

Then look at the 4th and realize that if you want to go down the path of validating that some string contains sane SQL prior to throwing that SQL at the database is vastly more complex than you seem to think it is: That colname can still be checked, but you shouldn't stop at checking if that is a valid column, you should also check if the column is of a type that is supported in an EXTRACT(YEAR from) operation.然后查看第 4 条并意识到,如果您想在将该 SQL 放入数据库之前验证某个字符串是否包含健全的 SQL 的路径比您想象的要复杂得多:仍然可以检查该colname ,但您不应停止检查它是否是有效列,您还应该检查该列是否属于EXTRACT(YEAR from)操作支持的类型。

Then realize that just about every SQL engine out there supports widely different SQL syntax and extensions, so you can't just write one SQL parser, you'd have to write one for psql, one for mysql, one for mssql, and so on.然后意识到几乎每个 SQL 引擎都支持广泛不同的 SQL 语法和扩展,因此您不能只编写一个 SQL 解析器,您必须为 psql 编写一个,为 mysql 编写一个,为 mssql 编写一个,等等.

Hopeless situation.无望的情况。

So, what to do?那么该怎么办?

Just run that stuff: Toss it at the DB.只需运行那些东西:将它扔到数据库中。 If it's invalid, the DB will tell you with an SQLException .如果它无效,DB 会用SQLException告诉你。 you can fetch the specific db error from this with sqlEx.getSQLState() .您可以使用sqlEx.getSQLState()从中获取特定的数据库错误。 Unfortunately, that string is entirely dependent on the underlying SQL engine, but fortunately, most SQL engines give highly specific machine parsable information.不幸的是,该字符串完全依赖于底层的 SQL 引擎,但幸运的是,大多数 SQL 引擎都提供了高度特定的机器可解析信息。 For example, if there's gobbledygook in there, psql would give you 42601 .例如,如果那里有 gobbledygook, psql 会给你42601 If you want to tell the difference, write an SQL statement with a specific problem you'd like to know about (such as using a colname that doesn't exist), run it, print the SQLState.如果您想区分不同之处,请使用您想了解的特定问题编写 SQL 语句(例如使用不存在的列名),运行它,打印 SQLState。 Now you know what to look for.现在你知道要寻找什么了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM