What is the best way to auto-generate INSERT statements for a SQL Server table?

前端 未结 23 1779
难免孤独
难免孤独 2020-11-22 09:47

We are writing a new application, and while testing, we will need a bunch of dummy data. I\'ve added that data by using MS Access to dump excel files into the relevant table

23条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-11-22 10:06

    I made a simple to use utility, hope you enjoy.

    • It doesn't need to create any objects on the database (easy to use on production environment).
    • You don't need to install anything. It's just a regular script.
    • You don't need special permissions. Just regular read access is enough.
    • Let you copy all the lines of a table, or specify WHERE conditions so only the lines you want will be generated.
    • Let you specify a single or multiple tables and different condition statements to be generated.

    If the generated INSERT statements are being truncated, check the limit text length of the results on the Management Studio Options: Tools > Options, Query Results > SQL Server > Results to Grid, "Non XML data" value under "Maximum Characters Retrieved".

        -- Make sure you're on the correct database
        SET NOCOUNT ON;
        BEGIN TRY
        BEGIN TRANSACTION
    
        DECLARE @Tables TABLE (
            TableName          varchar(50) NOT NULL,
            Arguments           varchar(1000) NULL
        );
    
        -- INSERT HERE THE TABLES AND CONDITIONS YOU WANT TO GENERATE THE INSERT STATEMENTS
        INSERT INTO @Tables (TableName, Arguments) VALUES ('table1', 'WHERE field1 = 3101928464');
        -- (ADD MORE LINES IF YOU LIKE) INSERT INTO @Tables (TableName, Arguments) VALUES ('table2', 'WHERE field2 IN (1, 3, 5)');
    
    
    
        -- YOU DON'T NEED TO EDIT FROM NOW ON.
        -- Generating the Script
        DECLARE @TableName  varchar(50),
                @Arguments  varchar(1000),
                @ColumnName varchar(50),
                @strSQL     varchar(max),
                @strSQL2    varchar(max),
                @Lap        int,
                @Iden       int,
                @TypeOfData int;
    
        DECLARE C1 CURSOR FOR
        SELECT TableName, Arguments FROM @Tables
        OPEN C1
        FETCH NEXT FROM C1 INTO @TableName, @Arguments;
        WHILE @@FETCH_STATUS = 0
        BEGIN
    
            -- If you want to delete the lines before inserting, uncomment the next line
            -- PRINT 'DELETE FROM ' + @TableName + ' ' + @Arguments
    
            SET @strSQL = 'INSERT INTO ' + @TableName + ' (';
    
            -- List all the columns from the table (to the INSERT into columns...)
            SET @Lap = 0;
            DECLARE C2 CURSOR FOR
            SELECT sc.name, sc.type FROM syscolumns sc INNER JOIN sysobjects so ON so.id = sc.id AND so.name = @TableName AND so.type = 'U' WHERE sc.colstat = 0 ORDER BY sc.colorder
            OPEN C2
            FETCH NEXT FROM C2 INTO @ColumnName, @TypeOfData;
            WHILE @@FETCH_STATUS = 0
            BEGIN
                IF(@Lap>0)
                BEGIN
                    SET @strSQL = @strSQL + ', ';
                END
    
                SET @strSQL = @strSQL + @ColumnName;
                SET @Lap = @Lap + 1;
                FETCH NEXT FROM C2 INTO @ColumnName, @TypeOfData;
            END
            CLOSE C2
            DEALLOCATE C2
    
            SET @strSQL = @strSQL + ')'
            SET @strSQL2 = 'SELECT ''' + @strSQL + '
    SELECT '' + ';
    
            -- List all the columns from the table again (for the SELECT that will be the input to the INSERT INTO statement)
            SET @Lap = 0;
            DECLARE C2 CURSOR FOR
            SELECT sc.name, sc.type FROM syscolumns sc INNER JOIN sysobjects so ON so.id = sc.id AND so.name = @TableName AND so.type = 'U' WHERE sc.colstat = 0 ORDER BY sc.colorder
            OPEN C2
            FETCH NEXT FROM C2 INTO @ColumnName, @TypeOfData;
            WHILE @@FETCH_STATUS = 0
            BEGIN
                IF(@Lap>0)
                BEGIN
                    SET @strSQL2 = @strSQL2 + ' + '', '' + ';
                END
    
                -- For each data type, convert the data properly
                IF(@TypeOfData IN (55, 106, 56, 108, 63, 38, 109, 50, 48, 52)) -- Numbers
                    SET @strSQL2 = @strSQL2 + 'ISNULL(CONVERT(varchar(max), ' + @ColumnName + '), ''NULL'') + '' as ' + @ColumnName + '''';
                ELSE IF(@TypeOfData IN (62)) -- Float Numbers
                    SET @strSQL2 = @strSQL2 + 'ISNULL(CONVERT(varchar(max), CONVERT(decimal(18,5), ' + @ColumnName + ')), ''NULL'') + '' as ' + @ColumnName + '''';
                ELSE IF(@TypeOfData IN (61, 111)) -- Datetime
                    SET @strSQL2 = @strSQL2 + 'ISNULL( '''''''' + CONVERT(varchar(max),' + @ColumnName + ', 121) + '''''''', ''NULL'') + '' as ' + @ColumnName + '''';
                ELSE IF(@TypeOfData IN (47, 39)) -- Texts
                    SET @strSQL2 = @strSQL2 + 'ISNULL('''''''' + RTRIM(LTRIM(' + @ColumnName + ')) + '''''''', ''NULL'') + '' as ' + @ColumnName + '''';
                ELSE -- Unknown data types
                    SET @strSQL2 = @strSQL2 + 'ISNULL(CONVERT(varchar(max), ' + @ColumnName + '), ''NULL'') + '' as ' + @ColumnName + '(INCORRECT TYPE ' + CONVERT(varchar(10), @TypeOfData) + ')''';
    
                SET @Lap = @Lap + 1;
                FETCH NEXT FROM C2 INTO @ColumnName, @TypeOfData;
            END
            CLOSE C2
            DEALLOCATE C2
    
            SET @strSQL2 = @strSQL2 + ' as [-- ' + @TableName + ']
    FROM ' + @TableName + ' WITH (NOLOCK) ' + @Arguments
    
            SET @strSQL2 = @strSQL2 + ';
    ';
            --PRINT @strSQL;
            --PRINT @strSQL2;
            EXEC(@strSQL2);
    
            FETCH NEXT FROM C1 INTO @TableName, @Arguments;
        END
        CLOSE C1
        DEALLOCATE C1
    
        ROLLBACK
    END TRY
    BEGIN CATCH
        ROLLBACK TRAN
        SELECT 0 AS Situacao;
        SELECT
            ERROR_NUMBER() AS ErrorNumber
            ,ERROR_SEVERITY() AS ErrorSeverity
            ,ERROR_STATE() AS ErrorState
            ,ERROR_PROCEDURE() AS ErrorProcedure
            ,ERROR_LINE() AS ErrorLine
            ,ERROR_MESSAGE() AS ErrorMessage,
            @strSQL As strSQL,
            @strSQL2 as strSQL2;
    END CATCH
    

提交回复
热议问题