Получение длины данных вместе со столбцами и таблицами в запросе SQL Server - PullRequest
2 голосов
/ 09 марта 2019

Поскольку я хочу, чтобы столбцы не были varchar(MAX) Я хочу видеть максимальную длину данных для каждого столбца, чтобы решить, каким должен быть новый размер.

У меня есть этот запрос для нахождения всех моих (n)varchar(MAX) столбцы.

SELECT [TABLE_NAME], [COLUMN_NAME]
FROM information_schema.columns
WHERE DATA_TYPE IN ('varchar', 'nvarchar')
  AND CHARACTER_MAXIMUM_LENGTH = -1
ORDER BY TABLE_NAME, COLUMN_NAME

Например, у меня есть таблица клиентов, и среди результатов выводится следующая таблица для моих клиентов

+------------+--------------+
| TABLE_NAME | COLUMN_NAME  |
+------------+--------------+
| customers  | name         |
| customers  | address      |
| customers  | postal_code  |
| customers  | city         |
| customers  | email        |
| customers  | phone_number |
+------------+--------------+

. Выполнение следующих запросов:

SELECT MAX(DATALENGTH(name)) FROM customers
SELECT MAX(DATALENGTH(address)) FROM customers
SELECT MAX(DATALENGTH(postal_code)) FROM customers
SELECT MAX(DATALENGTH(city)) FROM customers
SELECT MAX(DATALENGTH(email)) FROM customers
SELECT MAX(DATALENGTH(phone_number)) FROM customers

Я могу получить желаемый результат, но мне бы очень хотелось, чтобы это был всего один запрос, возвращающий что-то вроде:

+------------+--------------+------------+
| TABLE_NAME | COLUMN_NAME  | Datalength |
+------------+--------------+------------+
| customers  | name         |         93 |
| customers  | address      |        122 |
| customers  | postal_code  |          6 |
| customers  | city         |         44 |
| customers  | email        |         75 |
| customers  | phone_number |         18 |
+------------+--------------+------------+

Я пытался

SELECT 
    [TABLE_NAME], [COLUMN_NAME], 
    (SELECT MAX(DATALENGTH(COLUMN_NAME))
     FROM TABLE_NAME) AS 'MaxContentLength'
FROM information_schema.columns
WHERE DATA_TYPE IN ('varchar', 'nvarchar')
  AND CHARACTER_MAXIMUM_LENGTH = -1
ORDER BY TABLE_NAME, COLUMN_NAME

Но я получаю эту ошибку:

Сообщение 208, Уровень 16, Состояние 1, строка 1
Неверное имя объекта 'TABLE_NAME'

Как исправитьэта проблема (или есть другой способ сделать то, что я хочу?)

Ответы [ 3 ]

1 голос
/ 10 марта 2019

Это мой подход к решению вашего вопроса, возможно, не самый быстрый.

declare @tbl varchar(128), @fld varchar(128)
declare @res table (
    [Table_Name] varchar(128), [Column_Name] varchar(128), [DataLength] int)

declare c1 cursor local for
    select c.TABLE_NAME, c.COLUMN_NAME
    from INFORMATION_SCHEMA.COLUMNS c
    join INFORMATION_SCHEMA.TABLES t on 
        (t.TABLE_CATALOG = c.TABLE_CATALOG and 
         t.TABLE_SCHEMA = c.TABLE_SCHEMA and 
         t.TABLE_NAME = c.TABLE_NAME)
    where t.TABLE_TYPE <> 'VIEW' 
        and c.DATA_TYPE in ('varchar', 'nvarchar') 
        and c.CHARACTER_MAXIMUM_LENGTH = -1
open c1
fetch next from c1 into @tbl, @fld
while @@FETCH_STATUS=0
begin
    insert into @res
    exec ('select '''
          +@tbl+''' as [TABLE_NAME], '''
          +@fld+''' as [COLUMN_NAME], max(datalength('
          +@fld+')) as [DataLength] from '
          +@tbl)
    fetch next from c1 into @tbl, @fld
end    
close c1
deallocate c1

select * from @res
0 голосов
/ 09 марта 2019

Несколько запросов, использующих DATALENGTH , могут быть объединены в один.

непроверенный набросок блокнота

SELECT 
 [TABLE_NAME], 
 [COLUMN_NAME], 
 [Datalength]
FROM 
(
    SELECT 
     'customers' AS [TABLE_NAME], 
     MAX(DATALENGTH(name)) AS name,
     MAX(DATALENGTH(address)) AS address,  
     MAX(DATALENGTH(postal_code)) AS postal_code,
     MAX(DATALENGTH(city)) AS city,
     MAX(DATALENGTH(email)) AS email,
     MAX(DATALENGTH(phone_number)) AS phone_number
    FROM customers
) AS src
UNPIVOT  
(
  [Datalength] 
  FOR [COLUMN_NAME] IN   
  ([name], [address], [postal_code], [city], [email], [phone_number])  
) AS unpvt; 
0 голосов
/ 09 марта 2019

Это правильно для вас?

SELECT 
    I.TABLE_NAME, I.COLUMN_NAME, 
    (SELECT MAX(DATALENGTH(COLUMN_NAME))
     FROM information_schema.columns
     WHERE TABLE_NAME = I.TABLE_NAME) AS 'MaxContentLength'
FROM information_schema.columns AS I
WHERE I.DATA_TYPE IN ('varchar', 'nvarchar')
  AND CHARACTER_MAXIMUM_LENGTH = -1
ORDER BY I.TABLE_NAME, I.COLUMN_NAME
...