Master SQL Query - Найти все столбцы в 1 таблице, которые имеют больший тип, чем содержащий максимальное значение - PullRequest
0 голосов
/ 20 сентября 2011

Хорошо, например, у меня есть столбец varchar 200, но он имеет максимальное значение 25 varchar.Таким образом, этот запрос должен вернуть этот столбец.Этот запрос должен проходить через все столбцы в выбранной таблице и возвращать все результаты такого рода.Таким образом, мы можем исследовать структуру столбцов и предпринять соответствующие действия.

Что я имею в виду: «найдите мне все столбцы, которые определены как шире, чем наибольшее фактическое значение данных в них» *

1 Ответ

1 голос
/ 20 сентября 2011

Вы не указали, что такое RDBMS, поэтому я выбрал общий подход.Таблицы INFORMATION_SCHEMA, как правило, поддерживаются большими установками СУБД (это стандарт, несмотря ни на что).Если нет, настройте его в соответствии с доступными метаданными, а также с особенностями синтаксиса.Сам подход является здравым.

SET NOCOUNT ON;

-- Create a local table for processing
DECLARE
    @RESIZING TABLE
(
    resizing_id int identity(1,1) NOT NULL PRIMARY KEY
,   schemaname sysname
,   tablename sysname
,   columnname sysname
,   datatype sysname
,   max_length int
,   current_length int
);

-- Use the ANSI standard view for system meta data
-- to populate tables. Only focusing on varchar fields
-- as they are the only ones that will provide useful
-- sizing information. 
-- To make it work with chars, update the query individual
-- queries to perform a trim operation before calling len
-- and obviously update the data_type to include char
INSERT INTO
    @RESIZING 
SELECT
    ISC.TABLE_SCHEMA
,   ISC.TABLE_NAME
,   ISC.COLUMN_NAME
,   ISC.DATA_TYPE
,   ISC.CHARACTER_MAXIMUM_LENGTH
,   NULL AS current_length
FROM
    INFORMATION_SCHEMA.COLUMNS ISC
WHERE
    ISC.DATA_TYPE = 'varchar';


-- Create a cursor
-- Kill a kitten
DECLARE
    Csr CURSOR 
FOR
SELECT
    -- build out a query like
    -- SELECT @current_len = MAX(LEN(X.[COLUMN_NAME])) FROM [dbo].[TABLE] X WITH(NOLOCK) 
    'SELECT @current_len = MAX(LEN(X.[' 
    + R.columnname 
    + '])) FROM [' 
    + R.schemaname 
    + '].[' 
    + R.tablename 
    + '] X WITH(NOLOCK) ' AS query
,   R.current_length
FROM
    @RESIZING R
FOR UPDATE OF current_length;

-- 2 local variables, one for the dynamic query
-- one to hold the results of said query
DECLARE
    @query nvarchar(max)
,   @current_length int;

OPEN
    Csr;

FETCH NEXT 
FROM Csr
INTO @query, @current_length;

WHILE @@FETCH_STATUS = 0
BEGIN
    -- try before you buy
    PRINT @query;

    -- Run the query, assigning length to @current_length variable
    EXECUTE sp_executesql @query, N'@current_len int OUTPUT', @current_len = @current_length OUTPUT;

    -- Push results int our temporary table
    UPDATE
        R
    SET
        current_length = @current_length
    FROM
        @RESIZING R
    WHERE
        CURRENT OF Csr;

    FETCH NEXT 
    FROM Csr
    INTO @query, @current_length;
END

CLOSE Csr;
DEALLOCATE Csr;


-- Result the resultset for all the
-- tables with longer lengths than used
-- (NULLS included)
SELECT
    *
FROM
    @RESIZING R
WHERE
    R.max_length > isnull(@current_length, 0)

Результаты (SQL Server 2008 R2)

resizing_id | schemaname | tablename    | columnname | datatype | max_length | current_length
1           | dbo        | DupesOk      | name       | varchar  | 50         | 12
2           | dbo        | SALES_HEADER | CCCode     | varchar  | 15         | 15
3           | lick       | ABC          | value      | varchar  | 50         | 8
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...