T-SQL: как получить точную длину строки в символах?

я генерирую инструкции T-SQL SELECT для таблиц, для которых у меня нет информации о типе данных. В этих операторах мне нужно выполнить операции манипуляции строками, которые зависят от длины исходного значения столбцов таблиц.

один пример (но не единственный) - вставить текст в определенную позицию в строке, включая возможность вставить его в конце:

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

(случай, когда + LEN требуется, потому что материал не позвольте мне вставить текст в конец строки.)

проблема в том, что LEN исключает конечные пробелы, которые разрушат расчет. Я знаю, что могу использовать DATALENGTH, который не исключает конечные пробелы, но я не могу преобразовать байты, возвращаемые DATALENGTH, в символы, требуемые материалом, потому что я не знаю, является ли столбец продукта типом varchar или nvarchar.

Итак, как я могу создать инструкцию SQL, которая зависит от точной длины строки в символы без предварительной информации об используемом строковом типе данных?

5 ответов


вот что я в конечном итоге с помощью:

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 трюк примерно с той же скоростью, что и лен (...) один.

Спасибо за все хорошие ответы!


попробуйте это:

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

не можете ли вы найти информацию о типе для столбцов в системных таблицах?

Если нет, то определить, является ли столбец varchar или nvarchar это сделает это.

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

использовать DATALENGTH и SQL_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]

если нет пробелов, len(reverse(column_name)) даст вам длину столбца.