循环遍历所有表,然后循环遍历所有列数据类型

时间:2016-10-27 07:40:58

标签: sql-server tsql

我在Microsoft SQL Server Management Studio中创建存储过程,我想循环遍历所有表名,然后循环遍历所有列并捕获其数据类型,当数据类型为ntext时,我希望它将数据类型更改为为nvarchar(最大)

 USE [fmsStage]
 GO


/****** Object: StoredProcedure [dbo].[removenText] Script Date 10/27/2016 8:35:10 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


ALTER PROCEDURE [dbo].[spRemovenText]
AS

BEGIN
BEGIN TRANSACTION
    DECLARE @Table_Name nvarchar(50)
    DECLARE @Query nvarchar(250)
    DECLARE Table_Cursor CURSOR FOR SELECT Name FROM sys.tables ORDER BY Name ASC;
    DECLARE @Affected_Rows int = 0

    OPEN Table_Cursor
    FETCH NEXT FROM Table_Cursor INTO @Table_Name
    WHILE @@FETCH_STATUS = 0
    BEGIN
        print @Table_Name
        ALTER TABLE [fmsStage].[dbo].@Table_Name ALTER COLUMN
        FETCH NEXT FROM Table_Cursor INTO @Table_Name
    END
    SELECT @Affected_Rows AS Affected_Rows

    CLOSE  Table_Cursor
    DEALLOCATE Table_Cursor

    ROLLBACK 
END

打印@Table_Name会返回所有表名。但我无法弄清楚如何循环遍历所有字段/列名称以获取其数据类型以及何时数据类型为ntext将其更改为nvarchar(max)

更新:我现在彼此内部有两个循环。它让我回到所有数据类型。但是它没有给我回到列名,因为这里没有2个选择部分(对不起我的不好解释)这是我目前的代码:

USE [fmsStage]
GO


/****** Object: StoredProcedure [dbo].[removenText] Script Date 10/27/2016 8:35:10 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


ALTER PROCEDURE [dbo].[spRemovenText]
AS

BEGIN
BEGIN TRANSACTION
    DECLARE @Table_Name nvarchar(50)
    DECLARE @Column_Name nvarchar(50)
    DECLARE @Query nvarchar(250)
    DECLARE Table_Cursor CURSOR FOR SELECT Name FROM sys.tables ORDER BY Name ASC;
    DECLARE @Affected_Rows int = 0
    DECLARE @sql nvarchar(max)
    /******* Cursor for Loop 1 ******/
    OPEN Table_Cursor
    FETCH NEXT FROM Table_Cursor INTO @Table_Name
    WHILE @@FETCH_STATUS = 0
    BEGIN
        print @Table_Name
        /******* Cursor for Loop 2 *******/
        DECLARE Column_Cursor CURSOR FOR SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @Table_Name;
        OPEN Column_Cursor
        FETCH NEXT FROM Column_Cursor INTO @Column_Name
        WHILE @@FETCH_STATUS = 0
        BEGIN
            print @Column_Name

            FETCH NEXT FROM Column_Cursor INTO @Column_Name
        END
        CLOSE  Column_Cursor
        DEALLOCATE Column_Cursor
        FETCH NEXT FROM Table_Cursor INTO @Table_Name
    END

    CLOSE  Table_Cursor
    DEALLOCATE Table_Cursor

    ROLLBACK 
END

当我改变时:

DECLARE Column_Cursor CURSOR FOR SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @Table_Name;

进入这个:

DECLARE Column_Cursor CURSOR FOR SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @Table_Name;

或者这个:

DECLARE Column_Cursor CURSOR FOR SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @Table_Name;

它返回给我数据类型或列名称(取决于我实际选择的)但我希望它回馈这两件事。不只是数据类型或列名称

2 个答案:

答案 0 :(得分:4)

您可以在字符串中构建语句并动态执行它。这样你就不需要while循环了。

DECLARE @alter_stmts NVARCHAR(MAX) = (
    SELECT 
        ';ALTER TABLE '+
            QUOTENAME(t.TABLE_SCHEMA)+'.'+QUOTENAME(t.TABLE_NAME)+' '+
        'ALTER COLUMN '+
            QUOTENAME(c.COLUMN_NAME)+ ' NVARCHAR(MAX) ' + CASE WHEN c.IS_NULLABLE='YES' THEN 'NULL' ELSE 'NOT NULL' END 
    FROM 
        INFORMATION_SCHEMA.TABLES AS t
        INNER JOIN INFORMATION_SCHEMA.COLUMNS AS c ON
            c.TABLE_SCHEMA=t.TABLE_SCHEMA AND
            c.TABLE_NAME=t.TABLE_NAME
    WHERE
        t.TABLE_TYPE='BASE TABLE' AND
        c.DATA_TYPE LIKE '%NTEXT%'
    FOR
        XML PATH('')
)+';';

--SELECT @alter_stmts; -- review
EXEC sp_executesql @alter_stmts; -- execute it

答案 1 :(得分:1)

您可以创建如下语句来动态创建语句。

  • 一次性操作只需将结果复制到新的查询窗口,检查代码并执行。

  • 如果更频繁地执行,您可以使用CURSOR自动解决此问题。

尝试这样的事情:

修改

添加了对TABLE_TYPE='BASE TABLE' ...

的检查
SELECT 'ALTER TABLE ' + QUOTENAME(c.TABLE_CATALOG) + '.' + QUOTENAME(c.TABLE_SCHEMA) + '.' + QUOTENAME(c.TABLE_NAME) 
    + ' ALTER COLUMN ' + QUOTENAME(c.COLUMN_NAME) + ' VARCHAR(MAX) ' + CASE WHEN c.IS_NULLABLE='NO' THEN 'NOT NULL ' ELSE 'NULL ' END
FROM INFORMATION_SCHEMA.COLUMNS AS c
INNER JOIN INFORMATION_SCHEMA.TABLES AS t ON c.TABLE_CATALOG=t.TABLE_CATALOG AND c.TABLE_SCHEMA=t.TABLE_SCHEMA AND c.TABLE_NAME=t.TABLE_NAME
WHERE t.TABLE_TYPE='BASE TABLE' 
  AND c.DATA_TYPE='NTEXT';