Самое большое значение в базе данных

Я ищу SQL-запрос, который возвращает список из пяти самых больших значений в базе данных. Что-то вроде SELECT TOP(5) * FROM Database

Результатом будет:

table_name |  column_name | field_max_length

Упражнение состоит в том, чтобы найти поле, вызывающее проблему, превышающую максимальный размер данных, которые можно загрузить в Excel из SQL Server, для сортировки ниже проблемы:

Ошибка памяти: обнаружена запись (66341 байт), превышающая максимальный размер страницы объекта хранения (65528 байт).

Просто чтобы уточнить, я ищу иголку в стоге сена. Самое длинное значение в ячейке базы данных в 100 таблицах, вызывающее вышеуказанную ошибку.

Что вы понимаете под словом «самый большой»? Персонажи? Размер в байтах? Какое-то другое произвольное определение? Честно говоря, это звучит как проблема XY. Почему вам нужно это сделать?

Thom A 10.05.2024 12:50
SELECT TOP 10 OBJECT_NAME(OBJECT_ID) TableName, st.row_count FROM sys.dm_db_partition_stats st WHERE index_id < 2 ORDER BY st.row_count DESC может помочь вам начать
GuidoG 10.05.2024 12:59

Я упомянул проблему с текстовой памятью, которую хочу найти, плюс не имеет значения, байты это или символы, поскольку мне нужно наибольшее значение. Как удобнее.

Michal 10.05.2024 13:02

спасибо @GuidoG, это хорошо для одной таблицы, но у меня более 100, которые используются в SSAS, а затем в результате в Excel. В худшем случае мне придется пройти выше всех.

Michal 10.05.2024 13:05

Похоже, настоящая проблема заключается в том, что вы пытаетесь поместить в Excel очень длинные строковые/двоичные значения. Почему ты вообще это делаешь? Excel — не место для хранения таких значений.

Thom A 10.05.2024 13:11

Это часть табличной модели SSAS, которая используется со статическими данными, предоставленными пользователем. Эта ошибка появляется не в PowerBI, а только в Excel. Унаследованное решение.

Michal 10.05.2024 13:14

Вероятно, это не одно значение, которое слишком велико (занимает слишком много байтов), а комбинация значений, составляющих проблемную запись.

Hans Kesting 10.05.2024 14:27
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
7
96
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это будет работать в SQL Server 2017+. Если вы используете версию 2016 года, вам нужно будет использовать несколько подзапросов со «старым» методом FOR XML PATH. (Я этого не делаю; версия 2016 года находится только в расширенной поддержке, версия 2014 года почти устарела, а версии 2012 года и более ранние — конец жизни. Если вы используете такую ​​старую версию, вероятно, пришло время обновить ее.)

Это «работает» путем создания массивного динамического оператора, получения максимальной длины данных каждого столбца из таблицы, затем их отмены, вставки всех этих несведенных данных во (временную) таблицу и, наконец, получения TOP (5). Должны быть безопасны любые имена, требующие определения разделителей. Если у вас устаревшие типы данных (например, text), может возникнуть ошибка; в этом случае вам придется опустить эти столбцы.

DECLARE @SQL nvarchar(MAX),
        @CRLF nchar(2) = NCHAR(13) + NCHAR(10);

DECLARE @Delimiter nchar(3) = N',' + @CRLF;
WITH Statements AS(
    SELECT CONVERT(nvarchar(MAX),N'') + --Force to MAX
           N'WITH DataLengths AS(' + @CRLF +
           N'    SELECT N' + QUOTENAME(s.name,'''') + N' AS SchemaName,' + @CRLF +
           N'           N' + QUOTENAME(t.name,'''') + N' AS TableName,' + @CRLF +
           STRING_AGG(CONVERT(nvarchar(MAX),N'') + --Force to MAX
                      N'           MAX(DATALENGTH(' + QUOTENAME(c.name) + N')) AS ' + QUOTENAME(c.name),@Delimiter) + @CRLF +
           N'    FROM ' + QUOTENAME(s.name) + N'.' + QUOTENAME(t.name) + N')' + @CRLF +
           N'SELECT DL.SchemaName,' + @CRLF +
           N'       DL.TableName,' + @CRLF +
           N'       V.ColumnName,' + @CRLF +
           N'       V.MaxColumnLength' + @CRLF +
           N'FROM DataLengths DL' + @CRLF +
           N'     CROSS APPLY(VALUES' + @CRLF +
           STRING_AGG(CONVERT(nvarchar(MAX),N'') + --Force to MAX
                      N'                       (N' + QUOTENAME(c.name,'''') + N',DL.' +  QUOTENAME(c.name) + N')',@Delimiter) + N')V(ColumnName,MaxColumnLength);' AS Statement
    FROM sys.schemas s
         JOIN sys.tables t ON s.schema_id = t.schema_id
         JOIN sys.columns c ON t.object_id = c.object_id
    GROUP BY s.name,
             t.name)
SELECT @SQL = STRING_AGG(Statement,@CRLF)
FROM Statements;

--PRINT @SQL; --Uncomment to see the first 4,000 bytes of the statement

CREATE TABLE #DataLengths (SchemaName sysname,
                           TableName sysname,
                           ColumnName sysname,
                           MaxColumnLength bigint);
INSERT INTO #DataLengths (SchemaName,TableName,ColumnName,MaxColumnLength)
EXEC sys.sp_executesql @SQL;

SELECT TOP(5)
       SchemaName,
       TableName,
       ColumnName,
       MaxColumnLength
FROM #DataLengths
ORDER BY MaxColumnLength DESC;

DROP TABLE #DataLengths;

Другие вопросы по теме