Oracle 当您试图避免对字符串长度使用幻数时,clob类型是否在PL/SQL代码中使用了错误的做法?

Oracle 当您试图避免对字符串长度使用幻数时,clob类型是否在PL/SQL代码中使用了错误的做法?,oracle,types,plsql,Oracle,Types,Plsql,PL/SQL变量的声明需要为类varchar2类型设置长度: declare query varchar2(2000); begin for i in 1..100 loop query := query || to_char(i); end loop; dbms_output.put_line(query); end; / 当产品需求发生变化,循环范围变大(在我的示例中,将范围设置为1..1000)时,我在陷阱中运行,得到错误: ORA-06502: PL/SQL:

PL/SQL变量的声明需要为类varchar2类型设置长度:

declare
  query varchar2(2000);
begin
  for i in 1..100 loop
    query := query || to_char(i);
  end loop;
  dbms_output.put_line(query);
end;
/
当产品需求发生变化,循环范围变大(在我的示例中,将范围设置为1..1000)时,我在陷阱中运行,得到错误:

ORA-06502: PL/SQL: : буфер символьных строк слишком маленький ошибка числа или значения ORA-06512: на  line 5
所以我需要在任何地方增加查询长度,甚至使用一些更大的数字来预测未来

这太难看了。我不是PL/SQL的专家,但通过阅读官方文档,我发现了clob类型,它不需要长度,快速检查表明代码是有效的

PL/SQL代码不再像Pascal,而是更像Python/Ruby/Perl。我真的很喜欢

我只对动态构建的字符串应用类型转换,这些字符串不属于密集循环使用

这种技术是正确的还是我错了

PS我是PL/SQL编程的新手,所以问这样愚蠢的问题

PPS工作代码之一(简化):

如果要在SQL中操作大于4000字节或在PL/SQL中大于32 kB的字符串,则数据类型是唯一的实际选项


但是,对于小字符串,
CLOB
上的操作比
VARCHAR2
上的操作要贵一些,因此在处理大字符串时,您应该只使用
CLOB
数据类型。因此,
VARCHAR2
数据类型仍然有它的用途,不要过火,用CLOB替换所有字符串。

看看您的示例工作代码,我的理解是您希望动态生成一个视图定义,它由可能数百个union语句组成,每个union语句查询不同的表

类似的数据存储在数百个不同的表中!现在这是一个奇怪的数据库架构

无论如何,从性能角度来看,不建议盲目地用clob替换varcar2

您为什么不保留一个计数器/检查“eventCur”(eventRec)中的记录数


然后,您可以为该计数器选择一个最佳值,在该值上方可以使用clob数据类型,在该值下方可以使用varchar2数据类型。

pl/sql中的最大值为varchar2(32767)。如果您生成的动态查询比这个更大,我可能会对您的方法提出质疑。从技术上讲,CLOB可以拯救您,但我想看看这个查询是什么样子的@tbone为了防御,我只需要将每个不可预测的长度VARCHAR2声明为32767字节长?@tbone我使用这种可变长度字符串来创建动态查询,这样它们就不在任何循环中,并且没有性能问题(如果与表行上的循环相比)……是的,如果您认为它将是一个大字符串,请使用VARCHAR2(32767)。我不确定您创建查询的意思。您是否正在构建一个庞大的IN列表?(其中somecol IN('val1'、'val2'、'val3'、…'val1000'…)哦,不!没有任何大的'IN'…一个示例是动态地在多个表上创建视图(随着时间的推移,表计数会发生变化)。注意,我并没有用CLOB替换每个VARCHAR2。我的主要观点是,为动态构建字符串设置固定长度(长度取决于数据内容,而不是DDL)很难看……无论如何,感谢大家的兴趣+1感谢大家对这个问题的兴趣。+1.我一定要强调CLOB字符串不属于任何扩展循环)
queryStr := 'create or replace view "DATA_VIEW" ("DT", "MONEY", "EVENT") as ( ';
for eventRec in eventCur
loop
  queryStr := queryStr || 'select DT, MONEY, ' || eventRec.ID
    || ' EVENT from ' || eventRec.tbl || ' union ';
end loop;
queryStr := rtrim(queryStr, ' union ') || ')';
execute immediate queryStr;
commit;