2010-09-20 59 views
5

我正在爲沒有數據類型信息的表生成T-SQL SELECT語句。在這些語句中,我需要執行字符串操作操作,這些操作取決於表的列的原始值的長度。T-SQL:如何獲取字符串的確切長度?

一個實例(但不是唯一的)是插入在一個字符串在特定位置的一些文本,包括在端部以將其插入的選項:

SELECT 
    CASE WHEN (LEN ([t0].[Product] = 8) 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
    END 
FROM [OrderItem] [t0] 

(情況下,當+ LEN是因爲STUFF不允許我在字符串的末尾插入文本。)

問題是,LEN排除尾隨空白,這會破壞計算。 我知道我可以使用DATALENGTH,它不排除尾隨空白,但我不能將DATALENGTH返回的字節轉換爲STUFF所需的字符,因爲我不知道Product列是varchar類型還是nvarchar類型。

那麼,我怎樣才能生成一個SQL語句,它取決於字符串的確切長度,而不需要關於正在使用的字符串數據類型的預先信息?

回答

12

這裏是我最終使用:

SELECT 
    CASE WHEN ((LEN ([t0].[Product] + '#') - 1) = 8) 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
    END 
FROM [OrderItem] [t0] 

測量表明,LEN(。 .. +'#') - 1個技巧與LEN(...)單獨的速度大致相同。

感謝您的所有好的答案!

+0

+1適用於解決方案! – 2010-09-23 15:03:21

+0

+1這可能是一個有用的技巧。 – 2010-09-23 15:10:10

3

你不能查找系統表中列的類型信息嗎?

如果不是,那麼確定一列是否爲varcharnvarchar這樣做。

create table #test 
(
c varchar(50), 
n nvarchar(50) 
) 

insert into #test values ('1,2,3,4 ',N'1,2,3,4,5  ') 

SELECT 
     CASE 
       WHEN datalength(CAST(c AS nvarchar(MAX))) = datalength(c) 
       THEN 'c is nvarchar' 
       ELSE 'c is char' 
     END, 
     CASE 
       WHEN datalength(CAST(n AS nvarchar(MAX))) = datalength(n) 
       THEN 'n is nvarchar' 
       ELSE 'n is char' 
     END 
FROM #test 
+0

查找信息:很可能,但很難。我也不確定這將如何執行。 – 2010-09-20 11:24:41

+0

該測試也很有趣,但我認爲我喜歡REPLACE更好地關注結果語句的「可讀性」。 – 2010-09-20 11:25:46

+0

@Fabien - 我非常肯定,查找類型信息的效果要比對列中的每個字符串進行替換或對每個字符串進行強制轉換都要好。 – 2010-09-20 11:30:23

4

試試這個:

SELECT 
    CASE WHEN (LEN (REPLACE([t0].[Product],' ', '#') = 8) 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
    END 
FROM [OrderItem] [t0] 
+0

好主意,我應該有自己的這一個... – 2010-09-20 11:27:00

+0

這是非常低效的,因爲我的測量顯示。 – 2010-09-23 13:46:07

+1

然而,它的快速變化與閃電一樣快:LEN([t0]。[Product] +'#') - 1 這與LEN([t0]。[Product])的速度差不多。 .. – 2010-09-23 13:47:00

1

使用DATALENGTHSQL_VARIANT_PROPERTY

SELECT 
    CASE 
    WHEN 8 
     = DATALENGTH([t0].[Product]) 
    /CASE SQL_VARIANT_PROPERTY([t0].[Product],'BaseType') WHEN 'nvarchar' THEN 2 ELSE 1 END 
    THEN [t0].[Product] + 'test' 
    ELSE STUFF ([t0].[Product], 8, 0, 'test') 
    END 
FROM [OrderItem] [t0] 
+0

我測試過了,雖然看起來完全像我所需要的,但它不適用於varchar(max)/ nvarchar(max) - 因爲sql_variant不能保存這樣的值。 – 2010-09-23 13:45:45

0

如果沒有前導空白,len(reverse(column_name))會給你列的長度。

相關問題