有没有一种方法可以在不执行的情况下获取未知数据库查询的类型/名称?
时间:2020-03-06 15:02:13 来源:igfitidea点击:
我有一个Web应用程序,用户可以在其中输入任意sql查询,以便以后进行批处理。我们想在不实际执行查询的情况下验证查询的语法。一些查询将花费很长时间,这就是为什么我们不想执行它们。我正在使用Oracle的dbms_sql.parse来执行此操作。
但是,现在我需要知道结果集列的数量和类型。有没有办法在不实际执行查询的情况下执行此操作?也就是说,让Oracle解析查询并告诉我在实际执行查询时将返回什么结果数据类型/名称?我正在使用Oracle 10g,它是Java 1.5 / Servlet 2.4应用程序。
编辑:输入查询的用户已经是数据库上的用户。他们使用其数据库凭据向我的应用程序进行身份验证,并使用这些凭据执行查询。因此,仅通过与sqlplus连接,它们就无法发出无法运行的任何查询。
解决方案
我们应该能够准备一个SQL查询来验证语法并获取结果集元数据。准备查询不应执行它。
import java.sql.*; . . . Connection conn; . . . PreparedStatement ps = conn.prepareStatement("SELECT * FROM foo"); ResultSetMetadata rsmd = ps.getMetaData(); int numberOfColumns = rsmd.getColumnCount();
然后,我们可以获得有关结果集每一列的元数据。
如果要严格通过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包含几乎所有我们需要了解的有关列的信息。