【问题标题】:Is there a way to get types/names of an unknown db query without executing it?有没有办法在不执行它的情况下获取未知数据库查询的类型/名称?
【发布时间】:2010-09-14 20:54:52
【问题描述】:

我有一个 Web 应用程序,用户可以在其中输入任意 sql 查询以供以后进行批处理。我们想要验证查询的语法而不实际执行它。有些查询会花费很长时间,这就是我们不想执行它们的原因。我正在使用 Oracle 的 dbms_sql.parse 来执行此操作。

但是,我现在需要知道结果集列的数量和类型。有没有办法在不实际执行查询的情况下做到这一点?也就是说,让 Oracle 解析查询并告诉我在实际执行查询时将返回什么结果数据类型/名称?我使用的是 Oracle 10g,它是一个 Java 1.5/Servlet 2.4 应用程序。

编辑:输入查询的用户已经是数据库上的用户。他们使用他们的数据库凭据对我的应用程序进行身份验证,并使用这些凭据执行查询。因此,他们无法输入任何仅通过连接 sqlplus 无法运行的查询。

【问题讨论】:

  • 你让用户输入查询?这听起来非常危险。
  • 我赞成! “删除 * FROM ...”!
  • 我也投票反对这种做法!应该允许用户输入值,但不能输入代码。
  • 哈!我想我不是唯一一个讨厌 SQL*Plus 的人。他们制作了一个网络应用程序来绕过那个令人讨厌的 POS。

标签: sql database oracle plsql


【解决方案1】:

您应该能够准备 SQL 查询来验证语法并获取结果集元数据。准备查询不应该执行它。

import java.sql.*;
. . .
Connection conn;
. . .
PreparedStatement ps = conn.prepareStatement("SELECT * FROM foo");
ResultSetMetadata rsmd = ps.getMetaData();
int numberOfColumns = rsmd.getColumnCount();

然后你可以得到关于结果集每一列的元数据。

【讨论】:

  • conn.prepareStatement("SELECT * FROM foo"); 此行是否尝试连接数据库?如果 DB 宕机了怎么办……这还能用吗?
  • @KisHanSarsecHaGajjar,它必须连接到数据库以解析 SQL 语句并发现存在哪些列。如果数据库已关闭,则 none 您的 SQL 将起作用。
  • 您能否建议我们可以在不执行或连接到数据库的情况下获取查询列的任何替代方法?我想解析我们从用户输入获得的查询并从中获取列,但是在用户配置查询时,如果 DB 关闭,他不应该被阻止。
  • @KisHanSarsecHaGajjar,这是一个奇怪的请求。鉴于您无法执行该查询,为什么您需要在数据库关闭时准备查询?您需要能够解析 SQL 语法、根据您的 RDBMS 表和列的元数据生成访问计划以及评估 SQL 表达式的语义的代码。如果您拥有所有这些代码,那么您基本上将拥有一个正常工作的 SQL RDBMS,从这个意义上说,数据库将不会关闭!
【解决方案2】:

如果你想通过 pl/sql 严格执行此操作,则可以执行以下操作:

DECLARE 
  lv_stat varchar2(100) := 'select blah blah blah';
  lv_cur INTEGER;
  lv_col_cnt INTEGER;
  lv_desc DBMS_SQL.desc_tab;
BEGIN
  DBMS_SQL.parse(lv_cur,lv_stat,DBMS_SQL.NATIVE);
  DBMS_SQL.describe_columns(lv_cur,lv_col_cnt,lv_desc);
  FOR ndx in lv_desc.FIRST .. lv_desc.LAST LOOP
    DBMS_OUTPUT.PUT_LINE(lv_desc(ndx).col_name ||' '||lv_desc(ndx).col_type);
  END LOOP;
END;

DBMS_SQL.desc_tab 包含几乎所有您需要了解的有关列的信息。

【讨论】:

    猜你喜欢
    • 2015-02-05
    • 2020-02-14
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多