创建一个通用的 PreparedStatement 方法来检查 Table 中是否存在值

Create a generic PreparedStatement method to check if value does exist in a Table

我想创建一个通用的 PreparedStatement 方法。 我有任何原始数据类型的多个值,以及一个特定查询(SELECT COUNT(1) FROM TABLE WHERE COlUMN = ?),甚至具有相同查询的 2 个或更多值(SELECT COUNT(1) FROM TABLE WHERE COLUMN = ? AND COLUMN1 = ?) 要知道它是否确实存在,这些查询甚至可能来自任何 Connection/DB。

我现在遇到的问题是,对于每个 value/query 我必须创建一个新方法,我想创建一个 unique/least 方法来检查它。

Examples:
Check if 1, does exist in SELECT COUNT(1) FROM TABLE1, in database1
Check if "Hey", does exist SELECT COUNT(1) FROM TABLE1 in database1
Check if "Hey" and 2, does exist SELECT COUNT(1) FROM TABLE2 in database1
Check if "TEST-001-TEST", does exist SELECT COUNT(1) FROM TABLE1 in database2

Or Basically:
Check if any primitive data type, and any number values does exist in an specific query, in any connection/DB using PreparedStatement
...

首先,让我强调一下,我认为您应该为此使用一些经过测试的库。构建动态 SQL 是有风险的,如果您根据用户提供的数据构建 SQL,您可能很容易让自己受到 SQL 注入。

Elliot Frisch 链接到的 answer 包含不错的选项。

现在,这些查询构建器在幕后所做的实际上是根据您提供的数据构建 SQL 字符串。自己当然可以这样做。基本上,您构建一个采用 table 名称、列名列表和值列表的方法。

然后构建 SQL 字符串

StringBuilder sql = new StringBuilder();
sql.Append("SELECT 1 FROM ");
sql.Append(QuoteTableName(tableName));
sql.Append(" WHERE ");
bool firstCol = true;
for(String col: columns) {
   if(firstCol) {
      firstCol = false;
   } else {
      sql.Append(" AND ");
   }    
   sql.Append(QuoteColumnName(col));
   sql.Append(" = ?");    
}

现在您可以创建准备好的语句并绑定参数值。 PreparedStatement.setObject 在大多数情况下对于大多数原始值都可以正常工作。如果你 运行 在类型转换上遇到麻烦,你可以为 SQLType.

添加一个单独的参数
PreparedStatement stmt = connection.prepareStatement(sql.toString());
for(int i = 0; i < values.length; ++i) {
   Object val = values[i];
   stmt.setObject(i+1, val);
}

这里棘手的部分是引用 table 和列名。这将因数据库而异,据我所知,JDBC 中没有万无一失的方法。 如果有人能纠正我,我会很高兴。

我用 Java 编写了一种(当然是动态的)脚本语言,它具有 SQL 功能。查看这些相关的代码片段,看看它们是否对您有所帮助:

https://github.com/EngineHub/CommandHelper/blob/master/src/main/java/com/laytonsmith/core/functions/SQL.java#L173 https://github.com/EngineHub/CommandHelper/blob/master/src/main/java/com/laytonsmith/core/functions/SQL.java#L312

相关资料基本是:

要知道有多少个参数,我计算问号,但我可能应该使用 PreparedQuery.getParameterMetaData().getParameterCount()。除非有带有问号的硬编码字符串,否则两者都应该有效,但使用参数元数据需要与数据库的活动连接,这在我的情况下是不可取的。一旦知道应该有多少个参数(使用任一方法),就可以循环该次数,并使用各种 set*(i, value) 方法,其中 i 是 1-indexed 参数计数。您可以从 PreparedQuery.getParameterMetaData() 获得很多其他信息,包括使用 getParameterType() 的每个参数所需的类型。但是使用参数元数据是您问题的解决方案,您可以更深入地研究它以找到您需要的更多信息。