我们正在编写一个新的应用程序,在进行测试时,我们将需要一堆虚拟数据。我已经通过使用MS Access将excel文件转储到相关表中添加了这些数据。

每隔一段时间,我们想要“刷新”相关的表,这意味着将它们全部删除,重新创建它们,并运行已保存的MS Access追加查询。

第一部分(删除和重新创建)是一个简单的sql脚本,但最后一部分让我畏缩。我想要一个单独的设置脚本,它有一堆insert来重新生成虚拟数据。

我现在有数据在表格里。从该数据集自动生成一个大的INSERT语句列表的最佳方法是什么?

我能想到的唯一方法是将表保存到excel表格中,然后编写excel公式为每一行创建一个INSERT,这肯定不是最好的方法。

我使用2008 Management Studio连接到SQL Server 2005数据库。


当前回答

为了获得带有过滤记录的INSERT语句(WHERE QUERY),您可以

右击表脚本表>创建到>新的查询 用temp_table重命名 现在运行 选择到temp_table从你的第一个表,现在你的标准在这里

这样你的临时表将只有你想要的记录, 现在通过运行由@Mike Ritacco with DATA ONLY解释的脚本向导,您将得到确切的插入语句。

其他回答

这也可以使用Visual Studio完成(至少在2013年版本开始)。

在VS 2013中,也可以过滤insert语句所基于的行列表,据我所知,这在SSMS中是不可能的。

请执行以下步骤:

Open the "SQL Server Object Explorer" window (menu: /View/SQL Server Object Explorer) Open / expand the database and its tables Right click on the table and choose "View data" from context menu This will display the data in the main area Optional step: Click on the filter icon "Sort and filter data set" (the fourth icon from the left on the row above the result) and apply some filter to one or more columns Click on the "Script" or "Script to File" icons (the icons on the right of the top row, they look like little sheets of paper)

这将为活动窗口或文件的所选表创建(有条件的)插入语句。

Visual Studio 2013:滤镜和脚本

也许你可以试试SQL Server发布向导 http://www.microsoft.com/downloads/details.aspx?FamilyId=56E5B1C5-BF17-42E0-A410-371A838E570A&displaylang=en

它有一个向导,帮助您编写插入语句。

生产数据库中有数据吗?如果是这样,您可以通过DTS设置数据的周期刷新。我们每周都在周末进行测试,每周都有干净、真实的测试数据是非常好的。

如果你还没有生产,那么你应该创建一个他们想要的数据库(新鲜的)。然后,复制该数据库并使用新创建的数据库作为您的测试环境。当你想要一个干净的版本时,只需再复制一遍干净的版本,就可以了。

如果需要编程式访问,那么可以使用开源存储过程GenerateInsert。

插入语句生成器

作为一个简单而快速的例子,要为表AdventureWorks.Person.AddressType生成INSERT语句,执行以下语句:

USE [AdventureWorks];
GO
EXECUTE dbo.GenerateInsert @ObjectName = N'Person.AddressType';

这将生成以下脚本:

SET NOCOUNT ON
SET IDENTITY_INSERT Person.AddressType ON
INSERT INTO Person.AddressType
([AddressTypeID],[Name],[rowguid],[ModifiedDate])
VALUES
 (1,N'Billing','B84F78B1-4EFE-4A0E-8CB7-70E9F112F886',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
,(2,N'Home','41BC2FF6-F0FC-475F-8EB9-CEC0805AA0F2',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
,(3,N'Main Office','8EEEC28C-07A2-4FB9-AD0A-42D4A0BBC575',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
,(4,N'Primary','24CB3088-4345-47C4-86C5-17B535133D1E',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
,(5,N'Shipping','B29DA3F8-19A3-47DA-9DAA-15C84F4A83A5',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
,(6,N'Archive','A67F238A-5BA2-444B-966C-0467ED9C427F',CONVERT(datetime,'2002-06-01 00:00:00.000',121))
SET IDENTITY_INSERT Person.AddressType OFF

我做了一个简单易用的实用程序,希望你喜欢。

它不需要在数据库上创建任何对象(易于在生产环境中使用)。 你不需要安装任何东西。这只是一个普通的脚本。 您不需要特殊权限。常规的读访问就足够了。 允许您复制表的所有行,或指定WHERE条件,以便只生成您想要的行。 允许您指定要生成的单个或多个表和不同的条件语句。

如果生成的INSERT语句被截断,在Management Studio Options: Tools > Options, Query results > SQL Server > results to Grid,“Non XML data”value下的“Maximum Characters retrieve”中检查结果的限制文本长度。

    -- 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 (60, 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 (37, 47, 39, 0, 110)) -- 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