如何将表中的所有数据导出为可插入的SQL格式?

27 浏览
0 Comments

如何将表中的所有数据导出为可插入的SQL格式?

我在Microsoft SQL Server Management Studio中有一个数据库(称为A_db),其中有一个表(称为A_table),有10行数据。\n我还有另一个数据库(称为B_db),其中有一个与A_table具有相同列设置的表(称为B_table),但B_table是空的。\n我想要:\n从A_table复制每一行到B_table。\n在Microsoft SQL Server Management Studio 2012中是否有选项可以从表创建插入SQL?或者是否有其他选项可以做到这一点?

0
0 Comments

如何将表中的所有数据导出为可插入的SQL格式?

有一种方法可以通过DumpDataFromTable存储过程从表中将数据转储为文件:

EXEC dbo.DumpDataFromTable
      @SchemaName = 'dbo',
      @TableName = 'YourTableName',
      @FolderPath = N'c:\tmp\scripts\' -- 文件夹必须存在!!!

注意:SQL必须具有创建文件的权限,如果没有设置,则执行下面的命令:

EXEC sp_configure 'Ole Automation Procedures', 1;
RECONFIGURE WITH OVERRIDE;

使用此脚本,您可以调用存储过程DumpDataFromTable.sql,并一次转储多个表,而不是手动逐个从管理工具中进行操作。

生成的脚本默认格式为:

INSERT INTO  SELECT 

或者,您可以将生成的格式更改为:

SELECT ... FROM

通过设置变量@OutputType = 2。

完整的存储过程代码如下:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DumpDataFromTable]') AND type in (N'P', N'PC'))
    DROP PROCEDURE dbo.[DumpDataFromTable]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- 作者:Oleg Ciobanu
-- 创建日期:20171214
-- 版本:1.02
-- 描述:
-- 转储数据有两种格式
-- @OutputType = 1 : INSERT INTO 格式
-- @OutputType = 2 : SELECT * FROM 格式
--
-- SQL必须具有创建文件的权限,如果没有设置,则执行下面的命令:
-- EXEC sp_configure 'Ole Automation Procedures', 1; RECONFIGURE WITH OVERRIDE;
--
-- =============================================
CREATE PROCEDURE [dbo].[DumpDataFromTable]
(
      @SchemaName nvarchar(128) = 'dbo',
      @TableName nvarchar(128) = 'testTable',
      @AdditionalCondition nvarchar (1000) = '', -- 必须以AND开头
      @OutputType int = 1, -- 取值为1表示INSERT INTO格式,取值为2表示SELECT FROM格式
      @FolderPath nvarchar(250) = N'c:\tmp\scripts\', -- 文件夹必须存在!!!
      @FileName nvarchar(250) = NULL, -- 如果传入此值,将使用此值作为文件名
      @Debug int = 0
)
AS
BEGIN  
    SET NOCOUNT ON;
    -- 如果收到权限拒绝的错误,请执行下面的命令
    -- EXEC sp_configure 'Ole Automation Procedures', 1; RECONFIGURE WITH OVERRIDE;
    DECLARE @Script nvarchar (max)
    DECLARE @TableNameClean nvarchar (max) = ''
    DECLARE @ColumnNameClean nvarchar(max)
    DECLARE @ColumnList nvarchar(max)
    -- 清理数据
    SET @TableNameClean = REPLACE(REPLACE(@TableName,'[',''),']','')
    SET @ColumnNameClean = REPLACE(REPLACE(@ColumnName,'[',''),']','')
    SET @AdditionalCondition = NULLIF(@AdditionalCondition,'')
    SET @FileName = REPLACE(@ColumnName,'.','_')
    SET @FileName = COALESCE(@FolderPath + @TableNameClean + '.sql', @FolderPath + @TableNameClean + ISNULL('_' + @FileName,N'') + '.sql')
    -- 调试
    IF @Debug = 1
        PRINT @FileName
    -- 创建临时存储过程,用于生成脚本文件
    DECLARE @_WritereadFile VARCHAR(max) =
        'IF EXISTS (SELECT * FROM sys.objects WHERE type = ''P'' AND name = ''PRC_WritereadFile'')
       BEGIN
          DROP  Procedure  PRC_WritereadFile
       END;'
    EXEC (@_WritereadFile)
    -- 存储过程内容
    SET @_WritereadFile =
    'CREATE Procedure PRC_WritereadFile (
         @Recreate INT -- 0表示创建,1表示追加模式
       , @FilePath NVARCHAR(1000)
       , @FileName NVARCHAR(500)
       , @Text NVARCHAR(MAX)   
       )
    AS
        DECLARE @FileSystem INT
        DECLARE @FileHandle INT
        DECLARE @ForAppending INT
        DECLARE @ForReading INT
        DECLARE @ForWriting INT
        DECLARE @Result INT
        DECLARE @ErrorMessage NVARCHAR(1500) = ''Error creating FileSystemObject''
        -- 创建对象
        EXECUTE @Result = sp_OACreate ''Scripting.FileSystemObject'', @FileSystem OUTPUT
        IF @Result <> 0 BEGIN
            PRINT ''Scripting.FileSystemObject''
            GOTO Error_Handler
        END    
        -- 创建文件
        IF @Recreate = 0 BEGIN
            EXECUTE @Result = sp_OAMethod @FileSystem,''CreateTextFile'', @FileHandle OUTPUT, @FilePath + @FileName
            IF @Result <> 0 BEGIN
                PRINT ''CreateTextFile''
                GOTO Error_Handler
            END
        END ELSE BEGIN          
            EXECUTE @Result = sp_OAMethod @FileSystem,''OpenTextFile'', @FileHandle OUTPUT, @FilePath + @FileName, 8, 0 -- 8表示追加模式
            IF @Result <> 0 BEGIN
                PRINT ''OpenTextFile''
                GOTO Error_Handler
            END            
        END
        -- 写入文本
        EXECUTE @Result = sp_OAMethod @FileHandle, ''WriteLine'', NULL, @Text
        IF @Result <> 0 BEGIN
            PRINT ''WriteLine''
            GOTO Error_Handler
        END     
        -- 关闭文件
        EXECUTE @Result = sp_OAMethod @FileHandle,''Close''
        IF @Result <> 0 BEGIN
            PRINT ''Close''
            GOTO Error_Handler
        END
        -- 销毁对象
        EXECUTE sp_OADestroy @FileHandle
        EXECUTE sp_OADestroy @FileSystem
        GOTO Done
        Error_Handler:
            DECLARE @ErrorNumber VARCHAR(30), @ErrorDescription VARCHAR (200)       
            EXEC @Result = sp_OAGetErrorInfo @FileHandle, @ErrorNumber OUT, @ErrorDescription OUT
            PRINT ''*** ERROR ***''
            SELECT OLEResult = @Result, hr = CONVERT (binary(4), @ErrorNumber), source = @FileHandle, description = @ErrorDescription
        Done:
    '
    -- 调试
    IF @Debug = 1
        PRINT @_WritereadFile
    EXEC (@_WritereadFile) 
    -- 调试
    IF @Debug = 1
        PRINT @Script
    -- 构建查询脚本
    SET @Script = '
    SELECT
        u.rn
        , c.ORDINAL_POSITION as ColumnPosition
        , c.DATA_TYPE as ColumnType
        , u.ColumnName
        , u.ColumnValue
    FROM
    (SELECT
        ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn,
    '
    + CHAR(13) + @ColumnList 
    + CHAR(13) + 'FROM [' + @SchemaName + '].[' + @TableName + '] s'
    + CHAR(13) + 'WHERE 1 = 1'
    + CHAR(13) + COALESCE(@AdditionalCondition,'')
    + CHAR(13) + ') tt
    UNPIVOT
    (
      ColumnValue
      FOR ColumnName in ('
    + CHAR(13) + @ColumnNameClean
    + CHAR(13) + ')
    ) u
    LEFT JOIN INFORMATION_SCHEMA.COLUMNS c ON c.COLUMN_NAME = u.ColumnName
        AND c.TABLE_SCHEMA = ''' + @SchemaName + '''
        AND c.TABLE_NAME = ''' + @TableName + '''
    ORDER BY u.rn
            , c.ORDINAL_POSITION
    '
    -- 调试
    IF @Debug = 1
        PRINT @Script
    -- 准备数据表
    IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
        DROP TABLE #tmp
    CREATE TABLE #tmp
    (
        rn bigint
        ,ColumnPosition int
        ,ColumnType varchar (128)
        ,ColumnName varchar (128)
        ,ColumnValue nvarchar (2000)
    )
    SET @Script = 'INSERT INTO #tmp ' + CHAR(13) + @Script 
    -- 调试
    IF @Debug = 1
        PRINT @Script
    EXEC (@Script)
    -- 插入一个虚拟行,否则最后一个记录将无法处理 :)
    INSERT INTO #tmp (rn)
    SELECT MAX(rn) +  1 
    FROM #tmp   
    -- 调试
    IF @Debug = 1
        SELECT * FROM #tmp
    DECLARE @RowNumber bigint
        , @ColumnPosition int
        , @ColumnType varchar (128)
        , @ColumnName varchar (128)
        , @ColumnValue nvarchar (2000)
        , @Flag int = -1 -- 计数器/标志
        , @LineCount int = 1 -- 行计数器
        , @Line nvarchar(max) = NULL
        , @OutputScript nvarchar(max) = NULL
    DECLARE cur CURSOR FOR
    SELECT rn, ColumnPosition, ColumnType, ColumnName, ColumnValue
    FROM #tmp
    ORDER BY rn, ColumnPosition
    OPEN cur
    FETCH NEXT FROM cur
    INTO @RowNumber, @ColumnPosition, @ColumnType, @ColumnName, @ColumnValue
    -- 调试
    IF @Debug = 1
    BEGIN
        SET @OutputScript = 'SET NOCOUNT ON;' + CHAR(13)
        EXEC PRC_WritereadFile 1 /*Add*/, @FolderPath, @FileName, @OutputScript
        SET @OutputScript = ''
    END
    ELSE BEGIN
        SET @OutputScript = 'SET NOCOUNT ON;' + CHAR(13)
        SET @OutputScript = 
                        @OutputScript + 'SELECT *'
                        + CHAR(13) + 'FROM ('
                        + CHAR(13) + 'VALUES'
        EXEC PRC_WritereadFile 1 /*Add*/, @FolderPath, @FileName, @OutputScript
        SET @OutputScript = NULL
    END
    WHILE @_STATUS = 0
    BEGIN
        IF (@RowNumber <> @Flag) -- 新行
        BEGIN
            IF @OutputType = 1 -- 默认为INSERT INTO格式
            BEGIN
                SET @OutputScript = 'INSERT INTO [' + @SchemaName + '].[' + @TableName + '] ('
                                + CHAR(13) + @ColumnList
                                + CHAR(13) + ')'
                                + CHAR(13) + 'VALUES ('
                                + @OutputScript
                                + CHAR(13) + ');'
            END
            ELSE
            BEGIN
                -- 构建SELECT FROM格式
                IF (@RowNumber <> @Flag) -- 新行
                BEGIN
                    SET @OutputScript = COALESCE(@OutputScript + ',','') + '(' + @OutputScript + ')'
                    EXEC PRC_WritereadFile 1 /*Add*/, @FolderPath, @FileName, @OutputScript
                    SET @OutputScript = '' -- 在方法2中应清除脚本
                END            
            END
            -- 调试
            IF @Debug = 1
                PRINT @OutputScript
            EXEC PRC_WritereadFile 1 /*Add*/, @FolderPath, @FileName, @OutputScript
            -- 有新行
            -- 初始化变量
            SET @ColumnList = ''
            SET @OutputScript = NULL
            SET @Flag = @RowNumber
        END
        -- 构建插入值
        IF (@RowNumber = @Flag) -- 同一行
        BEGIN
            SET @ColumnList = COALESCE(@ColumnList + ',','') + '[' + @ColumnName + ']'
            SET @OutputScript =  CASE                              
                                    WHEN @ColumnType IN ('bit','tinyint','smallint','int','bigint'
                                                        ,'money','real','float','decimal','numeric','smallmoney')
                                    THEN
                                        COALESCE(@OutputScript + ',','') + '' + ISNULL(RTRIM(@ColumnValue),'NULL') + ''
                                    ELSE
                                        COALESCE(@OutputScript + ',','') + '''' + ISNULL(RTRIM(REPLACE(@ColumnValue, '''', '''''')),'NULL') + ''''         
                                END
        END
        FETCH NEXT FROM cur
        INTO @RowNumber, @ColumnPosition, @ColumnType, @ColumnName, @ColumnValue
        -- 调试
        IF @Debug = 1
        BEGIN
            PRINT CAST(@RowNumber AS VARCHAR) + '-' + CAST(@Flag AS VARCHAR)
        END
    END
    CLOSE cur
    DEALLOCATE cur
    IF @OutputType = 1
    BEGIN
        PRINT 'ignore'
    END
    ELSE BEGIN
        SET @OutputScript = CHAR(13) + ') AS vtable '
                        + CHAR(13) + ' (' + @ColumnList 
                        + CHAR(13) + ')'
        EXEC PRC_WritereadFile 1 /*Add*/, @FolderPath, @FileName, @OutputScript
        SET @OutputScript = NULL
    END
    PRINT 'Done: ' + @FileName
END

或者可以从https://github.com/Zindur/MSSQL-DumpTable/tree/master/Scripts下载最新版本。

它没有返回所有记录。我对一个包含3条记录的表进行了备份,但生成的脚本只有2条。

这是一个错误,我在github上修复了这个问题,请参见链接。

0
0 Comments

问题出现的原因是有人想要从一个表中导出所有数据到一个可插入的SQL格式中。解决方法有两种:

1. 如果目标表(B_table)没有自增列(identity column),可以使用以下代码将源表(A_table)的所有记录插入到目标表中:

INSERT INTO A_db.dbo.A_table
SELECT * FROM B_db.dbo.B_table

2. 如果目标表(B_table)有自增列(identity column),则需要指定要插入的列。基本上,选择除了自增列以外的所有列,自增列会默认自动递增。

SELECT *
INTO B_db.dbo.B_table
FROM A_db.dbo.A_table

如果在B_db中不存在B_table,上述代码将在B_db数据库中创建一个具有所有现有值的B_table表。

0
0 Comments

在SSMS 2017中,导出表中的所有数据并以可插入的SQL格式进行导出的方法如下:

1. 右键单击数据库

2. 指向“tasks”(在SSMS 2017中,您需要忽略第2步,因为生成脚本选项位于上下文菜单的顶级)。感谢Daniel的评论更新。

3. 选择“generate scripts”

4. 点击下一步

5. 选择表

6. 点击下一步

7. 点击高级

8. 滚动到“Types of data to script” - 在SMSS 2014中称为“types of data to script”。感谢Ellesedil的评论。

9. 选择“data only”

10. 点击“Ok”关闭高级脚本选项窗口

11. 点击下一步并生成脚本

通常我会将生成的脚本复制到一个新的查询编辑器窗口中,然后根据需要进行修改。

有人问是否可以生成UPDATE语句而不是插入语句。

警告:此工具以特定于文化的格式导出日期时间值。在其他服务器上可能无法导入。

有人评论说,如果导出包含NULL值的数据,则无法很好地工作。您将在结果中得到N'',并且两个单引号之间的字符将是二进制零。这将使结果无效,您将无法在SQL Server Management Studio中运行该脚本(未终止的字符串错误)。唯一的解决方法似乎是手动将所有内容更改为N'',或编写自己的替换工具以过滤掉零(因为没有文本编辑器会处理它,因为零只是字符串的结束)。

在SSMS 2017中,您需要忽略第2步 - 生成脚本选项位于上下文菜单的顶级。

是的,但是...如果只有一个表,您可以选择“script table as...” - “update”,但是对于所有表,您只能选择“DROP and CREATE”或“CREATE”在“Advanced”配置中。我正在使用SMSS 2019。

它要求连接字符串...为什么这么晦涩难懂。

它不会生成脚本中的数据。

我找不到v18.6中的生成脚本或任务选项。

在2023年的SSMS 18.12.1仍然有效。

0