@@ -315,6 +315,38 @@ private void checkClosed() throws SQLServerException {
315
315
"AND ic.key_ordinal = 0 " +
316
316
"ORDER BY t.name, i.name, ic.key_ordinal" ;
317
317
318
+ private static final String GET_FUNCTIONS_QUERY_BASE = "SELECT " +
319
+ "DB_NAME() AS FUNCTION_CAT, " +
320
+ "SCHEMA_NAME(o.schema_id) AS FUNCTION_SCHEM, " +
321
+ "o.name AS FUNCTION_NAME, " +
322
+ "-1 AS NUM_INPUT_PARAMS, " +
323
+ "-1 AS NUM_OUTPUT_PARAMS, " +
324
+ "-1 AS NUM_RESULT_SETS, " +
325
+ "CAST(NULL AS VARCHAR(254)) AS REMARKS, " +
326
+ "CASE o.type " +
327
+ "WHEN 'FN' THEN " + java .sql .DatabaseMetaData .functionReturnsTable + " " +
328
+ "WHEN 'IF' THEN " + java .sql .DatabaseMetaData .functionReturnsTable + " " +
329
+ "WHEN 'TF' THEN " + java .sql .DatabaseMetaData .functionReturnsTable + " " +
330
+ "ELSE " + java .sql .DatabaseMetaData .functionNoNulls + " " +
331
+ "END AS FUNCTION_TYPE " +
332
+ "FROM sys.all_objects o " +
333
+ "WHERE o.type IN (" ;
334
+
335
+ private static final String GET_PROCEDURES_QUERY_BASE = "SELECT " +
336
+ "DB_NAME() AS PROCEDURE_CAT, " +
337
+ "SCHEMA_NAME(o.schema_id) AS PROCEDURE_SCHEM, " +
338
+ "o.name AS PROCEDURE_NAME, " +
339
+ "-1 AS NUM_INPUT_PARAMS, " +
340
+ "-1 AS NUM_OUTPUT_PARAMS, " +
341
+ "-1 AS NUM_RESULT_SETS, " +
342
+ "CAST(NULL AS VARCHAR(254)) AS REMARKS, " +
343
+ "1 AS PROCEDURE_TYPE " +
344
+ "FROM sys.all_objects o " +
345
+ "WHERE o.type IN (" ;
346
+
347
+ private static final String FUNCTIONS_ORDER_BY = " ORDER BY FUNCTION_CAT, FUNCTION_SCHEM, FUNCTION_NAME" ;
348
+ private static final String PROCEDURES_ORDER_BY = " ORDER BY PROCEDURE_CAT, PROCEDURE_SCHEM, PROCEDURE_NAME" ;
349
+
318
350
// Use LinkedHashMap to force retrieve elements in order they were inserted
319
351
/** getColumns columns */
320
352
private LinkedHashMap <Integer , String > getColumnsDWColumns = null ;
@@ -432,6 +464,81 @@ private SQLServerResultSet getResultSetWithProvidedColumnNames(String catalog, C
432
464
return rs ;
433
465
}
434
466
467
+ /*
468
+ * Builds a filter string for object types based on the provided object types array.
469
+ *
470
+ * @param objectTypes
471
+ * Array of object types to be included in the filter.
472
+ *
473
+ * @return A string representing the filter for the object types.
474
+ */
475
+ private String buildObjectTypesFilter (String [] objectTypes ) {
476
+ return "'" + String .join ("', '" , objectTypes ) + "')" ;
477
+ }
478
+
479
+ /*
480
+ * Helper method to append catalog, schema, and object name filters to the query
481
+ */
482
+ private void appendFiltersAndOrderBy (StringBuilder queryBuilder , String catalog , String schemaPattern ,
483
+ String objectNamePattern , String orderByClause ) {
484
+
485
+ // Add catalog filter
486
+ if (catalog != null ) {
487
+ queryBuilder .append (" AND DB_NAME() = ?" );
488
+ }
489
+
490
+ // Add schema filter
491
+ if (schemaPattern != null && !schemaPattern .equals ("%" )) {
492
+ queryBuilder .append (" AND SCHEMA_NAME(o.schema_id) LIKE ?" );
493
+ }
494
+
495
+ // Add object name filter
496
+ if (objectNamePattern != null && !objectNamePattern .equals ("%" )) {
497
+ queryBuilder .append (" AND o.name LIKE ?" );
498
+ }
499
+
500
+ queryBuilder .append (orderByClause );
501
+ }
502
+
503
+ /*
504
+ * Executes a query against sys.objects to retrieve metadata about database objects.
505
+ * This method is used for both functions and procedures.
506
+ */
507
+ private SQLServerResultSet executeSysObjectsQuery (String catalog , String schemaPattern ,
508
+ String objectNamePattern , String query , String [] columnNames ) throws SQLException {
509
+
510
+ String orgCat = switchCatalogs (catalog );
511
+
512
+ try {
513
+ PreparedStatement pstmt = connection .prepareStatement (query );
514
+ pstmt .closeOnCompletion ();
515
+ int paramIndex = 1 ;
516
+
517
+ if (catalog != null ) {
518
+ pstmt .setString (paramIndex ++, escapeIDName (catalog ));
519
+ }
520
+ if (schemaPattern != null && !schemaPattern .equals ("%" )) {
521
+ pstmt .setString (paramIndex ++, escapeIDName (schemaPattern ));
522
+ }
523
+ if (objectNamePattern != null && !objectNamePattern .equals ("%" )) {
524
+ pstmt .setString (paramIndex ++, escapeIDName (objectNamePattern ));
525
+ }
526
+
527
+ SQLServerResultSet rs = (SQLServerResultSet ) pstmt .executeQuery ();
528
+
529
+ // Set the column names to match the expected format
530
+ for (int i = 0 ; i < columnNames .length ; i ++) {
531
+ rs .setColumnName (i + 1 , columnNames [i ]);
532
+ }
533
+ return rs ;
534
+
535
+ } finally {
536
+ if (null != orgCat ) {
537
+ connection .setCatalog (orgCat );
538
+ }
539
+ }
540
+ }
541
+
435
542
/**
436
543
* Switches the database catalogs.
437
544
*
@@ -947,23 +1054,34 @@ public java.sql.ResultSet getFunctions(String catalog, String schemaPattern,
947
1054
String functionNamePattern ) throws SQLException {
948
1055
checkClosed ();
949
1056
950
- /*
951
- * sp_stored_procedures [ [ @sp_name = ] 'name' ] [ , [ @sp_owner = ] 'schema'] [ , [ @sp_qualifier = ]
952
- * 'qualifier' ] [ , [@fUsePattern = ] 'fUsePattern' ]
953
- */ // use default ie use pattern matching.
954
1057
// catalog cannot be empty in sql server
955
1058
if (null != catalog && catalog .length () == 0 ) {
956
1059
MessageFormat form = new MessageFormat (SQLServerException .getErrString ("R_invalidArgument" ));
957
- Object [] msgArgs = {"catalog" };
1060
+ Object [] msgArgs = { "catalog" };
958
1061
SQLServerException .makeFromDriverError (null , null , form .format (msgArgs ), null , false );
959
1062
}
960
1063
961
- String [] arguments = new String [3 ];
962
- arguments [0 ] = escapeIDName (functionNamePattern );
963
- arguments [1 ] = escapeIDName (schemaPattern );
964
- arguments [2 ] = catalog ;
965
- return getResultSetWithProvidedColumnNames (catalog , CallableHandles .SP_STORED_PROCEDURES , arguments ,
966
- getFunctionsColumnNames );
1064
+ return getFunctionsFromSysObjects (catalog , schemaPattern , functionNamePattern , getFunctionsColumnNames );
1065
+ }
1066
+
1067
+ /*
1068
+ * Returns a ResultSet containing metadata about functions in the database.
1069
+ * This method queries the sys.all_objects system view to retrieve
1070
+ * information about functions, including their names, schemas, and types.
1071
+ */
1072
+ private SQLServerResultSet getFunctionsFromSysObjects (String catalog , String schemaPattern ,
1073
+ String functionNamePattern , String [] columnNames ) throws SQLException {
1074
+
1075
+ String [] functionTypes = { "FN" , "IF" , "TF" };
1076
+
1077
+ // Build the query
1078
+ StringBuilder queryBuilder = new StringBuilder (GET_FUNCTIONS_QUERY_BASE );
1079
+ queryBuilder .append (buildObjectTypesFilter (functionTypes ));
1080
+
1081
+ appendFiltersAndOrderBy (queryBuilder , catalog , schemaPattern , functionNamePattern , FUNCTIONS_ORDER_BY );
1082
+
1083
+ return executeSysObjectsQuery (catalog , schemaPattern , functionNamePattern , queryBuilder .toString (),
1084
+ columnNames );
967
1085
}
968
1086
969
1087
private static final String [] getFunctionsColumnsColumnNames = { /* 1 */ FUNCTION_CAT , /* 2 */ FUNCTION_SCHEM ,
@@ -1540,22 +1658,34 @@ public java.sql.ResultSet getProcedureColumns(String catalog, String schema, Str
1540
1658
1541
1659
@ Override
1542
1660
public java .sql .ResultSet getProcedures (String catalog , String schema ,
1543
- String proc ) throws SQLServerException , SQLTimeoutException {
1661
+ String proc ) throws SQLServerException , SQLTimeoutException , SQLException {
1544
1662
if (loggerExternal .isLoggable (Level .FINER ) && Util .isActivityTraceOn ()) {
1545
1663
loggerExternal .finer (toString () + ACTIVITY_ID + ActivityCorrelator .getCurrent ().toString ());
1546
1664
}
1547
1665
1548
1666
checkClosed ();
1549
- /*
1550
- * sp_stored_procedures [ [ @sp_name = ] 'name' ] [ , [ @sp_owner = ] 'schema'] [ , [ @sp_qualifier = ]
1551
- * 'qualifier' ] [ , [@fUsePattern = ] 'fUsePattern' ]
1552
- */
1553
- String [] arguments = new String [3 ];
1554
- arguments [0 ] = escapeIDName (proc );
1555
- arguments [1 ] = escapeIDName (schema );
1556
- arguments [2 ] = catalog ;
1557
- return getResultSetWithProvidedColumnNames (catalog , CallableHandles .SP_STORED_PROCEDURES , arguments ,
1558
- getProceduresColumnNames );
1667
+
1668
+ return getProceduresFromSysObjects (catalog , schema , proc , getProceduresColumnNames );
1669
+ }
1670
+
1671
+ /*
1672
+ * Returns a ResultSet containing metadata about stored procedures in the database.
1673
+ * This method queries the sys.all_objects system view to retrieve information about
1674
+ * procedures, including their names, schemas, and types.
1675
+ */
1676
+ private SQLServerResultSet getProceduresFromSysObjects (String catalog , String schemaPattern ,
1677
+ String procedureNamePattern , String [] columnNames ) throws SQLException {
1678
+
1679
+ String [] procedureTypes = { "P" , "PC" };
1680
+
1681
+ // Build the query
1682
+ StringBuilder queryBuilder = new StringBuilder (GET_PROCEDURES_QUERY_BASE );
1683
+ queryBuilder .append (buildObjectTypesFilter (procedureTypes ));
1684
+
1685
+ appendFiltersAndOrderBy (queryBuilder , catalog , schemaPattern , procedureNamePattern , PROCEDURES_ORDER_BY );
1686
+
1687
+ return executeSysObjectsQuery (catalog , schemaPattern , procedureNamePattern , queryBuilder .toString (),
1688
+ columnNames );
1559
1689
}
1560
1690
1561
1691
@ Override
0 commit comments