代码之家  ›  专栏  ›  技术社区  ›  mtruesdell

有没有一种方法可以在不执行的情况下获取未知数据库查询的类型/名称?

  •  4
  • mtruesdell  · 技术社区  · 18 年前

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

    但是,现在我需要知道结果集列的数量和类型。是否有一种方法可以在不实际执行查询的情况下完成此操作?也就是说,让Oracle解析查询,并告诉我实际执行查询时将返回什么结果数据类型/名称?我使用的是Oracle 10g,它是一个Java1.5/Services 2.4应用程序。

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

    2 回复  |  直到 17 年前
        1
  •  7
  •   Bill Karwin    18 年前

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

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

    然后,您可以获取关于结果集每一列的元数据。

        2
  •  4
  •   stjohnroe    17 年前

    如果您希望通过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_选项卡包含了关于列的几乎所有信息。