2017-08-04 161 views
1

下面是一個例子表:+和CONCAT的區別?

CREATE TABLE Example 
(
    LastName varchar(255), 
    FirstName varchar(255), 
    HomeAddress varchar(255), 
    City varchar(255) 
); 

INSERT INTO Example VALUES ('Murphy', 'James','123 Easy St', 'New York'); 
INSERT INTO Example VALUES ('Black', 'John','345 Youfarted St', 'Boston'); 
INSERT INTO Example VALUES ('Black', 'Amy','123 Simple St', 'Chicago'); 
INSERT INTO Example VALUES ('Simpson', 'Bill','123 Whofarted St', 'New York'); 
INSERT INTO Example VALUES ('Jones', 'James','321 Foo St', 'Chicago'); 
INSERT INTO Example VALUES ('Black', 'John','275 Ipsum St', 'Boston'); 
INSERT INTO Example VALUES ('Murphy', 'Sean','983 Ifarted St', 'New York'); 

我有2個不同的數據塊,其中之一是2012年,2008年等SO,我必須總是使這兩個工作的代碼處理。我有一個工作的2012年查詢(使用CONCAT()),但在2008年,試圖用'+'使用相同的查詢不會打印任何內容。

這工作:

DECLARE @sql2 NVARCHAR(max) 

SELECT 
    @sql2 = CONCAT(@sql2, ', COUNT(CASE WHEN city = ''', City, ''' THEN 1 END) as ', QUOTENAME(City)) 
FROM 
    Example 
GROUP BY City 

SET @sql2 = CONCAT('SELECT LastName', @sql2, ' FROM example GROUP BY LastName') 

EXEC sp_executesql @sql2 

將會產生的(這就是我想要的):

LastName Boston Chicago New York 
Black   2  0  0 
Jones   0  2  0 
Murphy   0  0  2 
Simpson   0  0  1 

此,不工作:

DECLARE @sql NVARCHAR(max) 

SELECT 
    @sql = @sql + ', COUNT(CASE WHEN city = ''' + City + ''' THEN 1 END) as ' + QUOTENAME(City) 
FROM 
    Example 
GROUP BY City 

SET @sql = 'SELECT LastName' + @sql + ' FROM example GROUP BY LastName' 

EXEC sp_executesql @sql 

通過「不起作用',我的意思是它不打印任何結果。我回來的是Command(s) completed successfully.

什麼給?

OH!並請在這個查詢的範圍內工作。我知道還有其他方法可以給這隻貓上皮,但這是我選擇的方式。 (我需要它是動態的,我需要它不使用PIVOT。)

+0

這是什麼節目?如果你試圖運行它返回結果呢? – xQbert

+0

@xQbert - 我不知道你的意思。 – lukehawk

+0

@WorkSmarter - 對不起,這是我抓住吸管。刪除這些不會做任何事情。 – lukehawk

回答

4

需要初始化聲明@sql NVARCHAR(MAX)=「」

原因:默認情況下,如果沒有初始化這將是空,concat會將null作爲空字符串處理,其中與+手動連接我們需要處理空值。

改變你的第一線,將工作+CONCAT之間


DECLARE @sql NVARCHAR(max) = '' --Initialize with empty string 

SELECT 
    @sql = @sql + ', COUNT(CASE WHEN city = ''' + City + ''' THEN 1 END) as ' + QUOTENAME(City) 
FROM 
    Example 
GROUP BY City 

SET @sql = 'SELECT LastName' + @sql + ' FROM example GROUP BY LastName' 

EXEC sp_executesql @sql 
+1

謝謝!我還添加了一個where子句,使其對可能在實際表中的NULL值進行強化(感謝@xQbert)。 – lukehawk

2

區別?

從我的觀點來看,+CONCAT函數之間的兩個主要區別是:

[1]當串聯NULLCONCAT將取代NULL與空字符串和最終結果將是NOT NULL

SELECT CONCAT('a', NULL, 'b') -- generates 'ab' 
同時使用 +會產生 NULL或什麼別的拼接根據 CONCAT_NULL_YIELDS_NULL

設置:

SET CONCAT_NULL_YIELDS_NULL ON -- Recommended setting 
SELECT 'a' + NULL + 'b' --> NULL 

SET CONCAT_NULL_YIELDS_NULL OFF 
SELECT 'a' + NULL + 'b' --> `ab` 

[2]當連接具有數字的字符串(例如),因爲data type precedence它使用+CONCAT會自動時極有可能得到一個錯誤/異常。轉換爲字符串([N]VARCHAR):

SELECT 'a' + 'b' + 123 -- End result: exception because `INT (123)` has a higher precedence than `VARCHAR(ab)` -> SQL Server will try to convert "everthing" to `INT` -> exception because 'ab' can't be converted to INTs 
----------- 
Msg 245, Level 16, State 1, Line 7 
Conversion failed when converting the varchar value 'ab' to data type int. 

SELECT CONCAT('a', 'b', 123) --> `ab123` 
如果你寫出來sp_execute @ SQL變量之前@SQL