问题描述
嗨,
我在Oracle 11g R2上。
我在创造一个假想的例子来模仿我的情况。我有一个函数,它把输入作为EMPID,它检查员工状态并返回工资。
Question:我在这里的问题是,对于使用字符串文本(=“Active”的状态检查,优化器是否会执行硬解析?将为会话中的多个emp_id调用此函数。
OR我是否应该用下面的变量替换字符串文字,以便Oracle优化程序不会对再次调用的同一SQL执行硬解析?
谢谢你。
我在Oracle 11g R2上。
我在创造一个假想的例子来模仿我的情况。我有一个函数,它把输入作为EMPID,它检查员工状态并返回工资。
FUNCTION f_salary (p_empid EMP.empid%TYPE)
RETURN NUMBER
IS
l_salary NUMBER;
BEGIN
SELECT salary
INTO l_salary
FROM emp
WHERE empid = p_empid
AND status = 'Active';
RETURN l_salary;
EXCEPTION
WHEN OTHERS
THEN
RETURN 0;
END f_salary;Question:我在这里的问题是,对于使用字符串文本(=“Active”的状态检查,优化器是否会执行硬解析?将为会话中的多个emp_id调用此函数。
OR我是否应该用下面的变量替换字符串文字,以便Oracle优化程序不会对再次调用的同一SQL执行硬解析?
FUNCTION f_salary (p_empid EMP.empid%TYPE)
RETURN NUMBER
IS
l_salary NUMBER;
l_status VARCHAR2(20) := 'Active';
BEGIN
SELECT salary
INTO l_salary
FROM emp
WHERE empid = p_empid
AND status = l_status;
RETURN l_salary;
EXCEPTION
WHEN OTHERS
THEN
RETURN 0;
END f_salary;谢谢你。
专家解答
考虑绑定变量的*动机*。它是为了避免发生100个、1000个或数百万个不同的SQL ,从而污染您的库缓存并导致解析问题。
请考虑以下理论应用,它具有一个查询:
选择*
来自EMP
其中emmpno = 123
and状态='Active'
和Sal = 500
如果这是唯一的查询,我曾经针对EMP运行,那么(根据定义)只有1个sql ,并且我不需要更改*any*的文字值来绑定,因为只有1个sql。
实际上,我们很可能会使用不同的雇员编号,因此empno的绑定是合适的。我们*可能*在查询中使用不同的薪水,因此对Sal的绑定也是合适的。
现在,如果我只有2个不同的可能状态值(活动/不活动) ,那么我就不需要用绑定替换它,因为根据定义,我只需要2个不同的SQL。
这里有一个可能的讨论-使用文本是否会威胁应用程序的可维护性。也就是说,如果有人编码为“Activ”(即,打字错误) ,那么有些人建议把它定义为(例如)一个常量来避免这种情况。
我倾向于使用文字...但我知道其他人倾向于在所有情况下使用定义的内容。
希望这个能帮上忙。
请考虑以下理论应用,它具有一个查询:
选择*
来自EMP
其中emmpno = 123
and状态='Active'
和Sal = 500
如果这是唯一的查询,我曾经针对EMP运行,那么(根据定义)只有1个sql ,并且我不需要更改*any*的文字值来绑定,因为只有1个sql。
实际上,我们很可能会使用不同的雇员编号,因此empno的绑定是合适的。我们*可能*在查询中使用不同的薪水,因此对Sal的绑定也是合适的。
现在,如果我只有2个不同的可能状态值(活动/不活动) ,那么我就不需要用绑定替换它,因为根据定义,我只需要2个不同的SQL。
这里有一个可能的讨论-使用文本是否会威胁应用程序的可维护性。也就是说,如果有人编码为“Activ”(即,打字错误) ,那么有些人建议把它定义为(例如)一个常量来避免这种情况。
我倾向于使用文字...但我知道其他人倾向于在所有情况下使用定义的内容。
希望这个能帮上忙。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




