Как сделать запрос, который возвращает (количество строк, имя таблицы) для каждой таблицы в базе данных? - PullRequest
1 голос
/ 21 июля 2009

Используя ANSI sql, как я могу сделать запрос, который возвращает (количество строк, имя таблицы) для каждого таблица в базе данных?

Спасибо Viki

Ответы [ 3 ]

2 голосов
/ 21 июля 2009

В той степени, в которой это возможно в «ANSI» (ISO) SQL, вам нужно перейти к представлениям информационной схемы, чтобы получить информацию. Официально это ИСО / МЭК 9075-11: 2003 (или 2008). См. Также статью в Википедии SQL , где говорится:

Часть SQL / Schemata, или Схемы информации и определения, определена в ISO / IEC 9075, Часть 11. SQL / Schemata определяет Информационную схему и Схему определения, предоставляя общий набор инструментов для самостоятельного создания баз данных и объектов SQL. -describing. Эти инструменты включают идентификатор объекта SQL, ограничения структуры и целостности, спецификации безопасности и авторизации, функции и пакеты ISO / IEC 9075, поддержку функций, предоставляемых реализациями СУБД на основе SQL, информацию о реализации СУБД на основе SQL и элементы определения размеров, а также значения, поддерживаемые реализациями СУБД. Эта часть стандарта содержит как обязательные, так и дополнительные функции.

Взять «обязательные функции» с щепоткой соли - я подозреваю, что большинство СУБД не реализуют даже обязательные части.

В противном случае ответ очень специфичен для СУБД. Информация доступна - детали отличаются от СУБД к СУБД, вот и все.


Раздел 5.61 SQL / Schemata (версия 2003) определяет «представление ТАБЛИЦ». Похоже, он не включает в себя количество строк, как и другие виды, которые я вижу. Таким образом, кажется, что комментарий Бо Сименсена является правильным; нет простого способа найти число строк переносимым образом.

CREATE VIEW TABLES AS
    SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME,
           TABLE_TYPE, SELF_REFERENCING_COLUMN_NAME, REFERENCE_GENERATION,
           USER_DEFINED_TYPE_CATALOG, USER_DEFINED_TYPE_SCHEMA,
           USER_DEFINED_TYPE_NAME, IS_INSERTABLE_INTO, IS_TYPED,
           COMMIT_ACTION
FROM DEFINITION_SCHEMA.TABLES
WHERE ( TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME ) IN
      ( SELECT TP.TABLE_CATALOG, TP.TABLE_SCHEMA, TP.TABLE_NAME
        FROM DEFINITION_SCHEMA.TABLE_PRIVILEGES AS TP
        WHERE ( TP.GRANTEE IN ( 'PUBLIC', CURRENT_USER )
                OR GRANTEE IN ( SELECT ROLE_NAMEFROM ENABLED_ROLES ) )
        UNION
        SELECT CP.TABLE_CATALOG, CP.TABLE_SCHEMA, CP.TABLE_NAME
        FROM DEFINITION_SCHEMA.COLUMN_PRIVILEGES AS CP
        WHERE ( CP.GRANTEE IN ( 'PUBLIC', CURRENT_USER )
                OR CP.GRANTEE IN ( SELECT ROLE_NAME
                                   FROM ENABLED_ROLES ) ) )
   AND TABLE_CATALOG = ( SELECT CATALOG_NAME
                         FROM INFORMATION_SCHEMA_CATALOG_NAME );

Как видно из списка выбора, количество строк не включено.

Поэтому я думаю, что не существует переносимого способа определения количества строк и имен таблиц.

0 голосов
/ 21 июля 2009

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

Например, для SQL Server вы можете использовать этот запрос, который входит в схему "sys", которая имеет все системные представления (SQL Server 2005 и выше):

SELECT 
    t.NAME AS TableName,
    i.name as indexName,
    p.[Rows],
    sum(a.total_pages) as TotalPages, 
    sum(a.used_pages) as UsedPages, 
    sum(a.data_pages) as DataPages,
    (sum(a.total_pages) * 8) / 1024 as TotalSpaceMB, 
    (sum(a.used_pages) * 8) / 1024 as UsedSpaceMB, 
    (sum(a.data_pages) * 8) / 1024 as DataSpaceMB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
WHERE 
    t.NAME NOT LIKE 'dt%' AND
    i.OBJECT_ID > 255 AND   
    i.index_id <= 1
GROUP BY 
    t.NAME, i.object_id, i.index_id, i.name, p.[Rows]
ORDER BY 
    object_name(i.object_id) 

Но это не сработает в Oracle, MySQL, PostgreSQL или IBM DB2, конечно .......

Марк

0 голосов
/ 21 июля 2009

лучший способ - написать процедуру, которая извлекает информацию из метаданных БД (Oracle - all_tables, MySql - information_schema.tables) и запускает запрос подсчета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...