代码之家  ›  专栏  ›  技术社区  ›  Abdu

将结果集从SQL导出到INSERT语句的工具?

  •  16
  • Abdu  · 技术社区  · 15 年前

    我想从SQL Server中导出一个特别的select查询结果集,以直接作为insert语句导出。

    当您右键单击SSMS时,我希望看到另存为选项“插入…”以及其他当前可用选项(csv、txt)。我没有从现有物理表中导出,也没有创建新表的权限,因此编写物理表脚本的选项对我来说不是一个选项。

    我必须从临时表或查询窗口中的结果集编写脚本。

    现在我可以导出到csv,然后将该文件导入到另一个表中,但这对于重复性工作来说是很费时的。

    当为空值创建值时,该工具必须创建适当的插入并理解数据类型。

    9 回复  |  直到 8 年前
        1
  •  11
  •   Mladen Prajdic    15 年前

    看看 SSMS Tools Pack SSMS插件,它允许您做您需要的事情。

        2
  •  13
  •   John MacIntyre    15 年前

    就我个人而言,我只需要针对表编写一个选择并自己生成插入。小菜一碟。

    例如:

    SELECT  'insert into [pubs].[dbo].[authors](
                        [au_id], 
                        [au_lname], 
                        [au_fname], 
                        [phone], 
                        [address], 
                        [city], 
                        [state], 
                        [zip], 
                        [contract])
        values( ''' + 
        [au_id] + ''', ''' + 
        [au_lname] + ''', ''' +
        [au_fname] + ''', ''' +
        [phone] + ''', ''' +
        [address] + ''', ''' +
        [city] + ''', ''' +
        [state] + ''', ''' +
        [zip] + ''', ' +
        cast([contract] as nvarchar) + ');'
    FROM    [pubs].[dbo].[authors]
    

    将生产

    insert into [pubs].[dbo].[authors](
                        [au_id], 
                        [au_lname], 
                        [au_fname], 
                        [phone], 
                        [address], 
                        [city], 
                        [state], 
                        [zip], 
                        [contract])
        values( '172-32-1176', 'White', 'Johnson', '408 496-7223', '10932 Bigge Rd.', 'Menlo Park', 'CA', '94025', 1);
    insert into [pubs].[dbo].[authors](
                        [au_id], 
                        [au_lname], 
                        [au_fname], 
                        [phone], 
                        [address], 
                        [city], 
                        [state], 
                        [zip], 
                        [contract])
        values( '213-46-8915', 'Green', 'Marjorie', '415 986-7020', '309 63rd St. #411', 'Oakland', 'CA', '94618', 1);
    ... etc ...
    

    几个陷阱:

    1. 别忘了把你的单曲包起来 引用
    2. 这假设一个干净的数据库,并且 不是SQL注入安全的。
        3
  •  4
  •   FoxMalder133    8 年前

    注意!!!!事实也是如此。在脚本的开头,您可以看到如何使用过程的示例。当然,如果需要,也可以进行insert expresion,或者为所需的转换添加数据类型。

    脚本的结果是concated select expresions with union all。 仔细整理数据库。我没有测试其他排序规则超过我的需要。

    对于长长度字段 我重新使用 [结果另存为..] 结果网格 代替复制 . 因为你可能会被剪下来的剧本。

    /*
    USE AdventureWorks2012
    GO
    
    IF OBJECT_ID('tempdb..#PersonTbl') IS NOT NULL
        DROP TABLE #PersonTbl;
    GO
    
    SELECT TOP (100)
            BusinessEntityID
          , PersonType
          , NameStyle
          , Title
          , FirstName
          , MiddleName
          , LastName
          , Suffix
          , EmailPromotion
          , CONVERT(NVARCHAR(MAX), AdditionalContactInfo) AS [AdditionalContactInfo]
          , CONVERT(NVARCHAR(MAX), Demographics) AS [Demographics]
          , rowguid
          , ModifiedDate
    INTO    #PersonTbl
    FROM    Person.Person
    
     EXEC dbo.p_GetTableAsSqlText
        @table_name = N'#PersonTbl'
    
    EXEC dbo.p_GetTableAsSqlText
        @table_name = N'Person'
        , @table_owner = N'Person'
    */
    /*********************************************************************************************/
    IF OBJECT_ID('dbo.p_GetTableAsSqlText', 'P') IS NOT NULL
        DROP PROCEDURE dbo.p_GetTableAsSqlText
    GO
    
    CREATE PROCEDURE [dbo].[p_GetTableAsSqlText]
        @table_name NVARCHAR(384) /*= 'Person'|'#Person'*/
      , @database_name NVARCHAR(384) = NULL /*= 'AdventureWorks2012'*/
      , @table_owner NVARCHAR(384) = NULL /*= 'Person'|'dbo'*/
     /*WITH ENCRYPTION, RECOMPILE, EXECUTE AS CALLER|SELF|OWNER| 'user_name'*/
    AS /*OLEKSANDR PAVLENKO p_GetTableAsSqlText ver.2016.10.11.1*/
        DECLARE @isTemporaryTable BIT = 0
    
    /*[DATABASE NAME]*/
        IF (PATINDEX('#%', @table_name) <> 0)
            BEGIN
                SELECT  @database_name = DB_NAME(2) /*2 - 'tempdb'*/
                      , @isTemporaryTable = 1
            END
        ELSE
            SET @database_name = COALESCE(@database_name, DB_NAME())
    /*END [DATABASE NAME]*/
    
    /*[SCHEMA]*/
        SET @table_owner = COALESCE(@table_owner, SCHEMA_NAME())
    
        DECLARE @database_nameQuoted NVARCHAR(384) = QUOTENAME(@database_name, '')
        DECLARE @table_ownerQuoted NVARCHAR(384) = QUOTENAME(@table_owner, '')
        DECLARE @table_nameQuoted NVARCHAR(384) = QUOTENAME(@table_name, '')
    
        DECLARE @full_table_name NVARCHAR(769)
     /*384 + 1 + 384*/
        DECLARE @table_id INT
    
        SET @full_table_name = CONCAT(@database_nameQuoted, '.', @table_ownerQuoted, '.', @table_nameQuoted)
        SET @table_id = OBJECT_ID(@full_table_name)
    
        CREATE TABLE #ColumnTbl
            (
             ColumnId INT
           , ColName sysname COLLATE DATABASE_DEFAULT
           , TypeId TINYINT
           , TypeName sysname COLLATE DATABASE_DEFAULT
           , TypeMaxLength INT
            ) 
    
        DECLARE @dynSql NVARCHAR(MAX) = CONCAT('
    INSERT INTO #ColumnTbl
    SELECT  ISC.ORDINAL_POSITION AS [ColumnId]
          , ISC.COLUMN_NAME AS [ColName]
          , T.system_type_id AS [TypeId]
          , ISC.DATA_TYPE AS [TypeName]
          , ISC.CHARACTER_MAXIMUM_LENGTH AS [TypeMaxLength]
    FROM    ', @database_name, '.INFORMATION_SCHEMA.COLUMNS AS [ISC]
            INNER JOIN ', @database_name, '.sys.objects AS [O] ON ISC.TABLE_NAME = O.name
            INNER JOIN ', @database_name, '.sys.types AS [T] ON ISC.DATA_TYPE = T.name
    WHERE   ISC.TABLE_CATALOG = "', @database_name, '"
            AND ISC.TABLE_SCHEMA = "', @table_owner, '"
            AND O.object_id = ', @table_id)
    
        IF (@isTemporaryTable = 0)
            SET @dynSql = CONCAT(@dynSql, '
            AND ISC.TABLE_NAME = "', @table_name, '"
    ')
        ELSE
            SET @dynSql = CONCAT(@dynSql, '
            AND ISC.TABLE_NAME LIKE "', @table_name, '%"
    ')
    
        SET @dynSql = REPLACE(@dynSql, '"', '''')
        EXEC(@dynSql)
    
        DECLARE @columnNamesSeparated NVARCHAR(MAX) = SUBSTRING((SELECT ', [' + C.ColName + ']' AS [text()]
                                                                 FROM   #ColumnTbl AS [C]
                                                                 ORDER BY C.ColumnId
                                                                FOR
                                                                 XML PATH('')
                                                                ), 2, 4000)
        --SELECT  @columnNamesSeparated
    
        DECLARE @columnNamesSeparatedWithTypes NVARCHAR(MAX) = SUBSTRING((SELECT    '+", " + "CONVERT(' + (CASE C.TypeId
                                                                                                             WHEN 231 /*NVARCHAR*/
                                                                                                             THEN CONCAT(C.TypeName, '(',
                                                                                                                         (CASE WHEN C.TypeMaxLength = -1 THEN 'MAX'
                                                                                                                               ELSE CONVERT(NVARCHAR(MAX), C.TypeMaxLength)
                                                                                                                          END), ')')
                                                                                                             WHEN 239 /*NCHAR*/
                                                                                                             THEN CONCAT(C.TypeName, '(', C.TypeMaxLength, ')') 
                                                                                                          /*WHEN -1 /*XML*/ THEN '(MAX)'*/
                                                                                                             ELSE C.TypeName
                                                                                                           END) + ', "+ COALESCE('
                                                                                    + (CASE C.TypeId
                                                                                         WHEN 56 /*INT*/ THEN 'CONVERT(NVARCHAR(MAX), [' + C.ColName + '])'
                                                                                         WHEN 40 /*DATE*/
                                                                                         THEN 'N"""" + CONVERT(NVARCHAR(MAX), [' + C.ColName + '], 101) + """"'
                                                                                         WHEN 60 /*MONEY*/ THEN 'CONVERT(NVARCHAR(MAX), [' + C.ColName + '])'
                                                                                         WHEN 61 /*DATETIME*/
                                                                                         THEN '"""" + CONVERT(NVARCHAR(MAX), [' + C.ColName + '], 21) + """"'
                                                                                         WHEN 104 /*BIT*/ THEN 'CONVERT(NVARCHAR(MAX), [' + C.ColName + '])'
                                                                                         WHEN 106 /*DECIMAL*/ THEN 'CONVERT(NVARCHAR(MAX), [' + C.ColName + '])'
                                                                                         WHEN 127 /*BIGINT*/ THEN 'CONVERT(NVARCHAR(MAX), [' + C.ColName + '])'
                                                                                         WHEN 189 /*TIMESTAMP*/
                                                                                         THEN 'N"""" + CONVERT(NVARCHAR(MAX), SUBSTRING([' + C.ColName
                                                                                              + '], 1, 8000), 1) + """"'
                                                                                         WHEN 241 /*XML*/
                                                                                         THEN '"""" + CONVERT(NVARCHAR(MAX), [' + C.ColName + ']) + """"'
                                                                                         ELSE 'N"""" + CONVERT(NVARCHAR(MAX), REPLACE([' + C.ColName
                                                                                              + '], """", """""")) + """"'
                                                                                       END) + ' , "NULL") + ") AS [' + C.ColName + ']"' + CHAR(10) COLLATE DATABASE_DEFAULT AS [text()]
                                                                          FROM      #ColumnTbl AS [C]
                                                                          ORDER BY  C.ColumnId
                                                                         FOR
                                                                          XML PATH('')
                                                                         ), 9, 100000)
    
    /*SELECT @columnNamesSeparated, @full_table_name*/
        DECLARE @dynSqlText NVARCHAR(MAX) = CONCAT(N'
    SELECT (CASE WHEN ROW_NUMBER() OVER (ORDER BY (SELECT   1 )) = 1 THEN "
    -- INSERT INTO ', @full_table_name, '
    --      (', @columnNamesSeparated, '
    --      )
    SELECT T.* --INTO #ResultTbl
    FROM (
    "
                    ELSE "UNION ALL "
                    END) + "SELECT "+ ', @columnNamesSeparatedWithTypes, ' FROM ', @full_table_name)
        SET @dynSqlText = CONCAT(@dynSqlText, ' UNION ALL SELECT ") AS [T]
    
    --SELECT *
    --FROM #ResultTbl
    "')
    
        SET @dynSqlText = REPLACE(@dynSqlText, '"', '''')
        --SELECT  @dynSqlText AS [XML_F52E2B61-18A1-11d1-B105-00805F49916B]
        EXEC(@dynSqlText)
    
        IF OBJECT_ID('tempdb..#ColumnTbl') IS NOT NULL
            DROP TABLE #ColumnTbl;
    GO
    
        4
  •  3
  •   Grinn Amber    9 年前

    这不完全是操作要求的,但是如果你想生成一个 insert 脚本 全部的 在表中记录,可以在SSMS中执行(至少2012年-可能是旧版本) 没有任何附加组件。

    右键单击包含包含数据的表的数据库,然后点击 任务>生成脚本 . 您将被带到一个向导,如下面所示。

    如果显示第一个屏幕,请单击“下一步”。 Just hit Next if this first screen is displayed.

    选择要为其生成脚本的表。 Select the table(s) for which you would like to generate the script.

    选择脚本的输出方式。 Select how you want your script outputted. (I like the "new query window" option)
    我喜欢“新查询窗口”选项。

    点击高级按钮并选择 仅数据 对于 要编写脚本的数据类型 Hit the Advanced button and select "Data only" for "Types of data to script"
    您可能需要查看这些选项,看看是否还有其他需要修改的内容。完成后点击OK。

    击中 接下来 直到你进入这个屏幕。一旦一切变绿,你就可以 插入 脚本! Hit Next until you get to this screen. Once everything goes green you'll have your script!
    我喜欢在测试脚本时让这个屏幕保持打开状态,看看是否需要做任何调整。

        5
  •  2
  •   Ian Jacobs    15 年前

    我知道这不完全是你要找的,但是你可以从select语句中插入:

    插入tbl(a,b) 从tbl2中选择c,d,其中c in(…)

    很明显,这很粗糙,但我希望这是我想说的重点。

        6
  •  2
  •   sleske    15 年前

    Squirrel SQL 也可以这样做。

    编写一个SQL查询,执行它进行测试。然后突出显示它,选择script/insert语句(不要记住确切的措辞)。

        7
  •  1
  •   Noah Yetter    15 年前

    蟾蜍可以从“数据网格”的“另存为”菜单中执行此操作。

        8
  •  1
  •   Tim Cooper    13 年前

    www.synametrics.com上的winsql有这个特性,而且非常方便。不确定该功能是否在免费版本中,但您可以让专业版试用30天。

    对于任何连接到ODBC的数据库来说,它是一个非常方便和易于使用的查询工具。

        9
  •  0
  •   Jesse    15 年前

    我为这个问题编写了一个脚本,可以在任何表上使用。(我说“应该”,因为脚本没有100%的测试,而且还有些粗糙。)您可以在 http://www.jessemclain.com/downloads/code/sql/spd_Tool_Get_Insert_Into_Values.sql.txt

    在托管公司附加的文件的底部有一些垃圾,只需去掉它。要运行,只需将@source_table的值更改为您的表。

    注意:我发布的文本文件在火狐3.0.11中呈现正常,但在IE7中没有。