ANSI SQL 표준 문자열 연결 연산자 II
상대적으로 ANSI 표준을 열심히 따르는 SQL Server의 이력을 생각한다면 충분히 공감이 됩니다. SQL Server에는 기존의 문자열 연결을 위해서 사용되는 방법들 예를 들어 + 연산자 또는 CONCAT() 함수가 있었습니다. 반면에 PostgreSQL과 같은 일부 DBMS에서는 || 연산자를 동일한 용도로 많이들 사용하죠 더불어 이것이 ANSI SQL 표준이기 때문에 다중 DBMS 환경을 사용하는 현실을 고려했을 때 그 만큼 필요성의 요구가 컸을 겁니다.
|| 연산자
두 개 이상의 문자 또는 문자열을 연결하는데 사용되는 연산자(Operator)이며 구문은 다음과 같이 간단합니다.
Expression || expression
여기서 Expression은 xml, json, image, ntext 또는 문자 및 인진 데이터 형식입니다. 반환 결과를 가장 큰 데이터 형식을 따릅니다(일반 형식은 8000에서 잘림). NULL 포함 시 결과 NULL입니다. 전체 설명은 Microsoft Learn 문서를 참조하세요.
간단한 예제는 아래와 같습니다.
SELECT 'Hello' || ',' || 'SQL Server 2025';
SELECT CustomerID, Address || ' in ' || City AS Addr
FROM Northwind.dbo.Customers;
GO
/*
길이 제한이 있는 경우
*/
DECLARE @a VARCHAR(8000) = REPLICATE('x', 8000);
DECLARE @b VARCHAR(MAX) = REPLICATE('y', 8000);
— 결과 길이는?
SELECT LEN(@a || @a) AS len_aa, LEN(@a || @b) AS len_ab;
GO
/*
NULL 결합은
*/
SELECT '' || 'SQL' || '';
SELECT 'Hello' || NULL || 'SQL Server 2025';
— 참고, CONCAT_NULL_YIELDS_NULL 설정(ON)을 따르지 않음
SET CONCAT_NULL_YIELDS_NULL OFF;
SET CONCAT_NULL_YIELDS_NULL ON;
혹시 SARG는 만족하나?
연산자이니 JOIN 조건이나 WHERE 조건에서도 사용되는 경우가 있겠죠? 그러면 인덱스 열에서도 인덱스 사용 가능한 조건(SARGable)식이 될 수 있을까? 간단한 예제로 확인해 봤습니다.
SET SHOWPLAN_ALL ON;
SELECT * FROM Northwind.dbo.Orders WHERE CustomerID = 'CENTC';
|–Index Seek(OBJECT:([Northwind].[dbo].[Orders].[CustomerID]), SEEK:([Northwind].[dbo].[Orders].[CustomerID]=N'CENTC') ORDERED FORWARD)
— Nope
SELECT * FROM Northwind.dbo.Orders WHERE CustomerID || '' = 'CENTC';
|–Clustered Index Scan(OBJECT:([Northwind].[dbo].[Orders].[PK_Orders]), WHERE:(([Northwind].[dbo].[Orders].[CustomerID]||N'')=N'CENTC'))
두 번째 예제에서 || 로 결합한 경우 Index Seek 연산을 사용하지 못하는 것을 알 수 있습니다. 성능상 주의가 필요하겠죠.
마치면서
|| 연산자에 익숙한 사용자들에게 도움이 많이 될 겁니다^^
감사합니다.


