oracle – 为什么我不应该创建所有PL / SQL-only VARCHAR2 32767
或者我应该?
(标题的灵感来自于Gary Myers在Why does Oracle varchar2 have a mandatory size as a definition parameter?年的评论) 考虑以下变量: declare -- database table column interfacing variable v_a tablex.a%type; -- tablex.a is varchar2 -- PL/SQL only variable v_b varchar2(32767); -- is this a poor convention ? begin select a into v_a from tablex where id = 1; v_b := 'Some arbitrary string: ' || v_a; -- ignore potential ORA-06502 insert into tabley(id,a) values(1,v_a); -- tablex.a and tabley.a types match v_b := v_b || ' More arbitrary characters'; end; / 变量v_a用于连接数据库表列,因此使用 变量v_b仅用于PL / SQL代码,通常返回到JDBC客户端(Java / Python程序,Oracle SOA / OSB等)或转储到平面文件(使用UTL_FILE).如果varchar2表示例如csv-line为什么我应该费心去计算确切的最大可能长度(除了验证该行在所有情况下都适合32767字节所以我不需要clob)并且每次我的数据模型改变时重新计算? 有很多问题涵盖了SQL中的varchar2长度语义,并解释了为什么varchar2(4000)在SQL中很糟糕.此外,SQL和PL / SQL varchar2-type之间的区别很好: > What is the size limit for a varchar2 PL/SQL subprogram argument in Oracle? 我讨论过这个问题的唯一地方是APC在answer中的第3点和第4点:
例如. Oracle PL / SQL编程,第5版作者:Steven Feuerstein没有提到声明varchar2变量太长的任何缺点,所以它不是一个严重的错误,对吧? 更新 经过一些谷歌搜索后,我发现Oracle文档在发布期间已经发展: 引用PL / SQL用户指南和参考10g第2版Chapter 3 PL/SQL Datatypes:
引用PL / SQL用户指南和参考11g第1版Chapter 3 PL/SQL Datatypes:
但PL / SQL用户指南和参考11g第2版Chapter 3 PL/SQL Datatypes不再提及内存分配,我根本找不到任何有关内存分配的信息. (我正在使用此版本,因此我只检查了11.2文档.)PL / SQL用户指南和参考12c版本1 Chapter 3 PL/SQL Datatypes也是如此. 我还发现Jeffrey Kemp的an answer也解决了这个问题.但Jeffrey的回答是指10.2文档,问题根本不是PL / SQL. 当Oracle实施不同的优化时,看起来这是PL / SQL功能在版本上发展的领域之一.请注意,这也意味着OP中列出的一些答案也是特定于发布的,即使这些问题/答案中没有明确提及.当时间过去并使用较旧的Oracle版本结束时(我在做白日梦?),这些信息将会过时(可能需要几十年的时间). 上面的结论由第12章调整PL / SQL语言参考11g R1 PL / SQL应用程序中的以下quote支持:
在11g R2或12c R1版本的文档中不再提及此问题.这符合第3章PL / SQL数据类型的演变. 回答: 从11gR2开始,它与使用varchar2(10)或varchar2(32767)的内存使用没有区别. Oracle PL / SQL编译器将以最佳方式为您处理脏信息! 对于11gR2之前的版本,有一个截止点,其中使用了不同的内存管理策略,每个版本的PL / SQL语言参考中都清楚地记录了这一点. 当没有可以从问题域派生的自然长度限制时,上述内容仅适用于PL / SQL专用变量.如果varchar2-variable表示GTIN-14,那么应该将其声明为varchar2(14). 当带有表列的PL / SQL变量接口使用%type-attribute时,这是使PL / SQL代码和数据库结构保持同步的零工作方式. 记忆测试结果: 我在Oracle Database 11g企业版11.2.0.3.0版中运行内存分析,结果如下: str_size iterations UGA PGA -------- ---------- ----- ------ 10 100 65488 0 10 1000 65488 65536 10 10000 65488 655360 32767 100 65488 0 32767 1000 65488 65536 32767 10000 65488 655360 因为PGA更改是相同的并且仅依赖于迭代而不是str_size,所以我认为varchar2声明的大小无关紧要.虽然测试可能太天真了 – 欢迎评论! 测试脚本: -- plsql_memory is a convenience package wrapping sys.v_$mystat s and -- sys.v_$statname tables written by Steven Feuerstein and available in the -- code-zip file accompanying his book. set verify off define str_size=&1 define iterations=&2 declare type str_list_t is table of varchar2(&str_size); begin plsql_memory.start_analysis; declare v_strs str_list_t := str_list_t(); begin for i in 1 .. &iterations loop v_strs.extend; v_strs(i) := rpad(to_char(i),10,to_char(i)); end loop; plsql_memory.show_memory_usage; end; end; / exit 测试运行示例: $sqlplus -SL <CONNECT_STR> @memory-test.sql 32767 10000 Change in UGA memory: 65488 (Current = 1927304) Change in PGA memory: 655360 (Current = 3572704) PL/SQL procedure successfully completed. $ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |