【发布时间】:2016-06-16 21:26:29
【问题描述】:
我们使用Oracle 10g 和Oracle 11g。
我们还有一个层来自动组合查询,来自用 .net 编写的伪 SQL 代码(类似于 Python 的 SqlAlchemy)。
我们的层目前将任何字符串用单引号 ' 包裹起来,如果包含非 ANSI 字符,它会自动将 UNISTR 与写成 unicode 字节的特殊字符(如 \00E0)组合起来。
现在我们使用以下构造创建了一个执行多次插入的方法:INSERT INTO ... (...)
SELECT ... FROM DUAL
UNION ALL SELECT ... FROM DUAL
...
该算法可以组合查询,其中相同的字符串字段有时被传递为'my simple string',有时被包装为UNISTR('my string with special chars like \00E0')。
所述条件导致ORA-12704: character set mismatch。
一种解决方案是使用INSERT ALL 构造,但与现在使用的相比,它非常慢。
另一个解决方案是指示我们的层将N 放在任何字符串的前面(除了那些已经用UNISTR 包裹的字符串)。这很简单。
我只是想知道这是否会对现有查询造成任何副作用。
注意:我们在 DB 上的所有字段都是 NCHAR 或 NVARCHAR2。
甲骨文参考:http://docs.oracle.com/cd/B19306_01/server.102/b14225/ch7progrunicode.htm
【问题讨论】:
-
如果您知道目标列的大小,也可以进行强制转换。或者您的图层可能支持适当的批量插入机制。但是肯定使用
n'...'只是避免了在插入过程中文字的隐式转换,从您的数据库字符集到国家字符集? -
@AlexPoole 真诚的,我不明白你的问题......
-
每条语句插入多少行?如果
INSERT ALL比UNION ALL慢,您可能会遇到Oracle 解析问题,正如我在回答here 中所解释的那样。将INSERT ALL分成更小的块可能就足以避免大型 SQL 语句的长时间解析。 -
@JonHeller 目前,我将 row-per-query 常量设置为
100。有了这个值,我可以在 ~21 秒内插入 81.000 行(x 23 列)。
标签: oracle unicode bulkinsert