【问题标题】:Master SQL Query - Find all colums in 1 table which have bigger type than containing maximum value主 SQL 查询 - 查找 1 个表中类型大于包含最大值的所有列
【发布时间】:2011-11-20 16:47:24
【问题描述】:

好吧,例如我有 varchar 200 列,但它有最大 25 个 varchar 值。所以这个查询应该返回这个列。此查询应遍历选定表中的所有列并返回所有此类结果。因此我们可以检查列结构并采取适当的措施。

我的意思是:“找到所有定义为比其中最大实际数据值更宽的列”

【问题讨论】:

  • 他的意思是“找到所有定义为比其中最大实际数据值更宽的列”
  • 您确实意识到在 varchar(8000) 中存储 10 个字符比在 varchar(10) 中存储更多的存储成本?我完全支持正确调整数据类型,不要误会。

标签: sql minimum required


【解决方案1】:

您没有说明什么 RDBMS,所以我尽可能地采用了一种通用的方法。大型 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

【讨论】:

  • 这是否只显示 char 列而不是 int 或 tiny int 等?
  • 根据您的问题,目前仅针对 varchar 设置。 ;) 处理整数类型的逻辑不会更难。十进制类型,那些会变得更丑
猜你喜欢
  • 2022-11-26
  • 2014-12-27
  • 2015-07-04
  • 1970-01-01
  • 2016-09-23
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多