Oracle字符串拼接应优先用||:CONCAT()仅支持两参数,||无此限;||遇NULL结果为NULL,需NVL/COALESCE显式处理;超4000字节须用DBMS_LOB.CONCAT();多行聚合首选LISTAGG()。
用 || 还是 CONCAT()?性能没差别,但写法有坑
oracle 里拼接字符串,|| 和 concat() 都能用,但别以为只是“换种写法”。concat() 只接受两个参数,传三个就直接报错:ora-00909: invalid number of arguments。而 || 没这个限制,写 a || b || c || d 完全合法。实际项目里如果硬套 concat(concat(a,b),c),不仅难读,还容易漏括号——尤其嵌套深了以后。
NULL 值会让 || 拼接结果变 NULL,不是空字符串
这是最常踩的隐性坑:只要参与拼接的任意一个值是 NULL,整个 || 表达式结果就是 NULL,不是你期待的跳过它继续拼。比如 'abc' || NULL || 'def' 返回的是 NULL,不是 'abcdef'。解决办法只有显式处理:NVL(col1, '') || NVL(col2, ''),或者用 COALESCE(col1, '', col2, '')(注意 COALESCE 是逐个判断非空,不支持直接拼接)。别指望数据库自动帮你忽略 NULL。
超长字符串(>4000 字节)必须用 DBMS_LOB.CONCAT()
普通 || 拼接在 PL/SQL 变量或 SQL 查询中,一旦总长度超过 4000 字节(比如拼一堆 CLOB 字段或大文本),就会报 ORA-06502: PL/SQL: numeric or value error: character string buffer too small。这时候不能硬撑,得切到 LOB 上:DBMS_LOB.CONCAT(lob1, lob2)。注意两点:输入必须是 CLOB 类型(不是 VARCHAR2),且函数返回仍是 CLOB,后续不能再直接和 VARCHAR2 混用。如果源头是 VARCHAR2,先用 TO_CLOB() 转一次。
批量拼接多行数据?别手写循环,用 LISTAGG() 代替
想把查询结果的多行某字段拼成一行(比如把用户所有订单号拼成逗号串),很多人第一反应是在 PL/SQL 里开游标、循环、累加字符串变量。这不仅慢,还容易触发内存溢出。正确姿势是单条 SQL 用 LISTAGG():SELECT LISTAGG(order_id, ',') WITHIN GROUP (ORDER BY order_date) FROM orders WHERE user_id = 123。它原生支持去重(加 DISTINCT)、截断(ON OVERFLOW TRUNCATE)、分组聚合,比任何手工拼接都稳。唯一要注意的是 Oracle 11g R2+ 才支持,老版本得用 WM_CONCAT()(不推荐,无官方支持)或自定义聚合函数。
真正麻烦的从来不是“怎么拼”,而是拼之前要不要 trim、要不要判空、拼之后要不要截断、要不要防 SQL 注入(比如拼动态表名时)。这些细节不处理,再短的 || 也埋雷。


















