使用Function查找未使用绑定变量的SQL

如何监控并找出系统中存在的大量的未使用绑定变量的SQL呢?利用TOM大师写的一个函数,我们可以按以下的方法进行查找。

测试环境:10G R2,Red Hat Enterprise Linux Server release 5.2

1.使用DBA用户登录ORACLE,刷新共享池,清除出共享池内的SQL。

SQL> conn /as sysdba
Connected.
SQL> alter system flush shared_pool;

System altered.

2.创建测试表,并且执行没有使用绑定变量的SQL。

SQL> conn scott/oracle
Connected.
SQL> create table t2 (a number);

Table created.

SQL> insert into t2 values(1);

1 row created.

SQL> insert into t2 values(2);

1 row created.

SQL> insert into t2 values(3);

1 row created.

SQL> insert into t2 values(4);

1 row created.

SQL> insert into t2 values(5);

1 row created.

SQL> insert into t2 values(6);

1 row created.

SQL> insert into t2 values(7);

1 row created.

SQL> insert into t2 values(8);

1 row created.

SQL> insert into t2 values(9);

1 row created.

SQL> commit;

Commit complete.
 

3.使用TOM大师的脚本创建函数。

CREATE OR REPLACE FUNCTION remove_constants (p_query IN varchar2)
   RETURN varchar2
AS
   l_query       long;
   l_char        varchar2 (1000);
   l_in_quotes   boolean DEFAULT FALSE ;
BEGIN
   FOR i IN 1 .. LENGTH (p_query)
   LOOP
      l_char := SUBSTR (p_query, i, 1);

      IF (l_char = '''' AND l_in_quotes)
      THEN
         l_in_quotes := FALSE;
      ELSIF (l_char = '''' AND NOT l_in_quotes)
      THEN
         l_in_quotes := TRUE;
         l_query := l_query || '''#';
      END IF;

      IF (NOT l_in_quotes)
      THEN
         l_query := l_query || l_char;
      END IF;
   END LOOP;

   l_query := TRANSLATE (l_query, '0123456789', '@@@@@@@@@@');

   FOR i IN 0 .. 8
   LOOP
      l_query := REPLACE (l_query, LPAD ('@', 10 - i, '@'), '@');
      l_query := REPLACE (l_query, LPAD (' ', 10 - i, ' '), ' ');
   END LOOP;

   RETURN UPPER (l_query);
END;
/

 

5.复制出一张v$sqlarea的表。

SQL> create table t1 as select sql_text,sql_text sql_text_wo_constants from v$sqlarea;

Table created.

SQL> commit;

Commit complete.

 

6.找出未使用绑定变量的问题SQL。

SQL> update t1 set sql_text_wo_constants = remove_constants(sql_text);

512 rows updated.

SQL>   SELECT   sql_text_wo_constants, COUNT ( * )
        FROM   t1
    GROUP BY   sql_text_wo_constants
      HAVING   COUNT ( * ) > 5
    ORDER BY   2;

SQL_TEXT_WO_CONSTANTS            COUNT(*)
------------------------------ ----------
INSERT INTO T@ VALUES(@)                9


 

 





 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL 自定义函数允许你在数据库查询过程中创建特定的功能和操作,并且可以给自定义函数返回的结果设置别名。这种做法能够使结果集更具可读性和直观性。以下是关于 SQL 自定义函数变量取别名的一些基本解释: ### 自定义函数概述 在 SQL 中,自定义函数是一个用户定义的过程,用于封装一组特定的 SQL 操作。它可以接受输入参数并返回一个值或结果集。通过创建自定义函数,你可以复用复杂的查询逻辑,并将其应用于整个数据仓库系统中。 ### 变量和别名 当执行自定义函数时,可以将变量作为输入传递给该函数。这些变量可以在函数内部处理,并生成所需的结果。结果不仅可以直接存储到数据库表中,也可以输出为包含多种列的数据结构。在这种情况下,结果集中的每一行都可以包含多个字段,每个字段通常都有一个描述性的名称(即“别名”),这有助于理解和呈现数据。 ### 给结果集的列设置别名 在 SQL 查询中,`AS` 关键字可用于给列、表或其他表达式设置别名。例如,在 SELECT 语句中,你可以指定 `SELECT column_name AS alias;` 来给某个列设置别名。这种方式不仅增强了代码的可读性,还使得在后续的引用时更加清晰明了。 ### 示例 假设我们有一个名为 `employees` 的表,它包含了员工的基本信息,如 `employee_id`, `first_name`, `last_name`, `salary` 等字段。我们可以创建一个简单的自定义函数来计算每个员工的全名及其年薪总和。 ```sql CREATE FUNCTION employee_details_summary(employee_id INT) RETURNS TABLE ( full_name VARCHAR(100), total_salary DECIMAL(10,2) ) AS $$ BEGIN RETURN QUERY SELECT CONCAT(first_name, ' ', last_name) AS full_name, salary * 12 AS total_salary FROM employees WHERE employee_id = $1; END; $$ LANGUAGE plpgsql; ``` 在这个例子中,`CONCAT(first_name, ' ', last_name)` 和 `salary * 12` 分别产生了全名和年薪总和的结果,并且这两个结果都被明确地分配了别名 `full_name` 和 `total_salary`。这个自定义函数可以简化对员工薪酬相关数据的分析过程,同时通过别名提高了查询结果的可理解性。 ### 相关问题: 1. **如何在 SQL 查询中自动为所有列添加别名?** 虽然 SQL 标准不支持为所有列一次性批量添加别名,但在某些特定 SQL 实现中(比如 PostgreSQL 或者某些 SQL Server 版本)可能会提供扩展功能或 UDF(用户定义函数)来实现类似的效果。通常的做法是在 SELECT 子句中明确列出每一个需要别名的列。 2. **SQL 中的变量如何影响自定义函数的性能?** 使用变量可以在自定义函数中存储中间结果,进而减少重复计算的次数。然而,如果变量使用不当(如过早绑定大量数据)可能导致内存消耗增加,进而影响整体性能。优化策略包括合理使用局部变量,避免不必要的复杂运算以及考虑使用更高效的算法和数据结构。 3. **在哪些场景下使用自定义函数和别名是最有效的?** 自定义函数和别名通常在需要重用复杂查询逻辑、提高查询结果可读性、管理和分发大量数据以及优化查询性能的场景中最有效。它们尤其适用于数据分析报告生成、数据清洗脚本、业务规则实施等领域。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值