2011-09-20 57 views
0

好吧例如我有varchar 200列,但它具有最大值爲25的varchar值。所以這個查詢應該返回這個列。該查詢應該貫穿選定表格中的所有列並返回所有這類結果。所以我們可以檢查列結構並採取適當的行動。主SQL查詢 - 查找1個表中的所有列的類型比包含最大值的類型更大

我的意思是:「找我被定義爲比他們最大的實際數據值更寬的所有列」

+1

他的意思是「找到我,被定義爲比他們最大的實際數據值更寬的所有列」 – Bohemian

+0

感謝編輯的問題:d – MonsterMMORPG

+0

你做意識到你不需要花費更多的存儲空間來存儲varchar(8000)中的10個字符而不是varchar(10)?我完全支持正確的數據類型,請不要誤解我的意思。 – billinkc

回答

1

你沒有指出哪些RDBMS,所以我盡我所能採取的辦法一般。 INFORMATION_SCHEMA表通常受到大型RDBMS安裝的支持(這是一個標準,儘管它值得)。如果沒有,調整這個以適應可用的元數據以及語法古怪。這種方法本身很健全。

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 
+0

這是否只顯示字符列不int或小int等等? – MonsterMMORPG

+1

它目前只針對你的問題設置了varchar。 ;)處理整個數字類型的邏輯不會更難。十進制類型,那些會變得更醜陋 – billinkc

+0

你可以請修改顯示數字:D謝謝。 – MonsterMMORPG

相關問題