SSMS:如何从 excel 导入 (Copy/Paste) 数据

SSMS: How to import (Copy/Paste) data from excel

如何 Copy/Paste 跟随来自 excel 的分隔数据(默认情况下用制表符分隔):

declare @t_values   nvarchar(max)   =                   
N'                
NULL    490366  NULL    NULL
NULL    490400  NULL    NULL
NULL    490402  NULL    NULL
483061  490404  10  abc1
NULL    490406  NULL    NULL
9766167 490408  3   abc2'
;

我的温度 table:

CREATE TABLE #insertTable
(   transaction_id int     
   ,user_id        int 
   ,purchase_price decimal(8,2) 
   ,mess           varchar(8)
);

?

注意!不使用 OPENROWSET

INSERT INTO的解决方案:

  1. (fast way to creae snippets )

SELECT INTO的解决方案:

  1. (fast way to creae snippets )

P.S. 如果你有旧的 SQL 服务器版本(数据库兼容集低于 130),你将需要单独 STRING_SPLIT功能。我建议关注 .

请使用以下过程:

CREATE PROCEDURE dbo.p_values2insertquery
    @t_name   nvarchar(128),                   -- Destination Table Name + [(column names)]
    @t_values nvarchar(max),                   -- Paste Table Values here (from excel for instance)    
    @dlm      nvarchar(128)   = N'  '          -- Delimiter: HT = HorizontalTab = char(9)
AS
/*  p_values2insertquery
        - converts table values stored in @t_values string (separated by default by @dlm=TAB)
          to queries for insert to  table name defined in @t_name


    INPUT:
        @t_name   nvarchar(128),                   -- Destination Table Name + [(column names)]
        @t_values nvarchar(max),                   -- Paste Table Values here (from excel for instance)    
        @dlm      nvarchar(128)   = N'  '          -- Delimiter: HT = HorizontalTab = char(9)

    -- NB! Script do NOT write any ifo to any table
    -- to perform insert please copy/paste script output and execute            


    EXAMPLE:

        IF OBJECT_ID('tempdb..#insertTable') IS NOT NULL DROP TABLE #insertTable;
        CREATE TABLE #insertTable
        (   transaction_id int     
           ,user_id        int 
           ,purchase_price decimal(8,2) 
           ,mess           varchar(8)
        );

        declare @t_name     nvarchar(128)   = '#insertTable'    -- Table Name for insert
        declare @t_values   nvarchar(max)   =                   -- Paste Table Values here (from excel for instance)
        N'                
        NULL    490366  NULL    NULL
        NULL    490400  NULL    NULL
        NULL    490402  NULL    NULL
        483061  490404  10  abc1
        NULL    490406  NULL    NULL
        9766167 490408  3   abc2'
        ;
        declare @dlm        nvarchar(128)   = char(9);          -- Delimiter: HT = char(9) = HorizontalTab

        exec p_values2insertquery @t_name, @t_values

     -- Output:
     insert into #insertTable VALUES(NULL,'490366',NULL,NULL);
     insert into #insertTable VALUES(NULL,'490400',NULL,NULL);
     insert into #insertTable VALUES(NULL,'490402',NULL,NULL);
     insert into #insertTable VALUES('483061','490404','10','abc1');
     insert into #insertTable VALUES(NULL,'490406',NULL,NULL);
     insert into #insertTable VALUES('9766167','490408','3','abc2');
*/
    select N'insert into '
            + @t_name               -- table name
            + ' VALUES(' 
            + replace               -- replace 'NULL' by NULL
              ( '''' 
                 + replace          -- surround values by quotes 'value1','value2'...
                   (    value
                   ,    @dlm        -- Delimiter: HT = char(9) = HorizontalTab
                   ,    ''','''
                   ) 
                 + ''''
              , '''NULL'''  
              , 'NULL'      
              )                                              
            + ');' as insertQuery
    --into #t 
    from string_split               -- insert Line per Row into table
         (  replace                 -- replace CR + LF by LF  (CR - Carriage Return, LF - Line Feed)
            (   @t_values           -- Paste Table Values here (from excel for instance)
            , char(13)+char(10)     -- CR + LF
            , char(10)              -- LF
            )
         ,char(10)
         ) 
    where len(value)>0              -- skip empty rows
    ;

/* the same, but step by step (for explanatory purposes):
IF OBJECT_ID('tempdb..#t') IS NOT NULL DROP TABLE #t;

select @t_values=replace(@t_values,char(13)+char(10), char(10))           ;    -- replace CR + LF by LF  (CR - Carriage Return, LF - Line Feed)
select value into #t from string_split(@t_values,char(10))                ;    -- insert Line per Row into table
delete from #t where len(value)<1                                         ;    -- delete empty lines

update #t set value =  '''' + replace(value,  @dlm, ''',''') + '''';            -- surround values by quotes 'value1','value2'...
update #t set value =      replace(value, '''NULL''', 'NULL');                  -- replace 'NULL' by NULL
update #t set value = N'insert into '+ @t_name + ' VALUES(' + value + ');'

select * from #t
*/
RETURN 0 

示例:

IF OBJECT_ID('tempdb..#insertTable') IS NOT NULL DROP TABLE #insertTable;
CREATE TABLE #insertTable
(   transaction_id int     
   ,user_id        int 
   ,purchase_price decimal(8,2) 
   ,mess           varchar(8)
);

declare @t_name     nvarchar(128)   = '#insertTable'    -- Table Name for insert
declare @t_values   nvarchar(max)   =                   -- Paste Table Values here (from excel for instance)
N'                
NULL    490366  NULL    NULL
NULL    490400  NULL    NULL
NULL    490402  NULL    NULL
483061  490404  10  abc1
NULL    490406  NULL    NULL
9766167 490408  3   abc2'
;
declare @dlm        nvarchar(128)   = char(9);          -- Delimiter: HT = char(9) = HorizontalTab

exec p_values2insertquery @t_name, @t_values

输出(只是Copy/Paste并执行执行插入):

insert into #insertTable VALUES(NULL,'490366',NULL,NULL);
insert into #insertTable VALUES(NULL,'490400',NULL,NULL);
insert into #insertTable VALUES(NULL,'490402',NULL,NULL);
insert into #insertTable VALUES('483061','490404','10','abc1');
insert into #insertTable VALUES(NULL,'490406',NULL,NULL);
insert into #insertTable VALUES('9766167','490408','3','abc2');

如果由于某种原因您不想使用 PROC(例如没有权限),您可以改用代码段。

请将此代码另存为扩展名为 .snippet 的文件,并通过 Code Snippets Manager:

将其添加到您的代码片段中
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>InsertTable</Title>    <!--InsertTable.snippet -copy/paste for filename-->
            <Shortcut></Shortcut>
            <Description>Prepare Copy/Paste Excel data for inserting to Table</Description>
            <Author>Denis Sipchenko</Author>
            <SnippetTypes>
                <SnippetType>SurroundsWith</SnippetType>    <!--SurroundsWith/Expansion-->
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal> <ID>t_name</ID>     <Default>'#insertTable'</Default>     <ToolTip>Destination Table Name [(column names)]</ToolTip>                            </Literal>
                <Literal> <ID>t_values</ID>   <Default></Default>                   <ToolTip>copy/paste Excel data here</ToolTip>                        </Literal>
                <Literal> <ID>delimiter</ID>  <Default>char(9)</Default>            <ToolTip>Column Delimiter: HT = char(9) = HorizontalTab</ToolTip>    </Literal>
            </Declarations>
            <Code Language="SQL">
                <![CDATA[-- NB! Script do NOT write any ifo to any table
-- to perform insert please copy/paste script output and execute

declare @tbl_name   nvarchar(128)   = $t_name$;     -- Destination Table Name + [(column names)]
declare @dlm        nvarchar(128)   = $delimiter$;  -- Delimiter: HT = char(9) = HorizontalTab
declare @tbl        nvarchar(max)   =               -- Paste Table Values here (from excel for instance)
N'$t_values$'
;

select N'insert into '
        + @tbl_name             -- table name
        + ' VALUES(' 
        + replace               -- replace 'NULL' by NULL
          ( '''' 
             + replace          -- surround values by quotes 'value1','value2'...
               (    value
               ,    @dlm        -- Delimiter: HT = char(9) = HorizontalTab
               ,    ''','''
               ) 
             + ''''
          , '''NULL'''  
          , 'NULL'      
          )                                              
        + ');' as insertquery
--into #t 
from string_split            -- insert Line per Row into table
     (  replace                 -- replace CR + LF by LF  (CR - Carriage Return, LF - Line Feed)
        (   @tbl                -- Paste Table Values here (from excel for instance)
        , char(13)+char(10)     -- CR + LF
        , char(10)              -- LF
        )
     ,char(10)
     ) 
where len(value)>0              -- skip empty rows


$selected$$end$
]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

屏幕:

请尝试以下操作:

-- NB! Script do NOT write any ifo to any table
-- to perform insert please copy/paste script output to the @tbl variable and execute

declare @tbl_name   nvarchar(128)   = '#insertTable';     -- Destination Table Name + [(column names)]
declare @dlm        nvarchar(128)   = char(9);  -- Delimiter: HT = char(9) = HorizontalTab
declare @tbl        nvarchar(max)   =               -- Paste Table Values here (from excel for instance)
N'NULL    490366  NULL    NULL
NULL    490400  NULL    NULL
NULL    490402  NULL    NULL
483061  490404  10  abc1
NULL    490406  NULL    NULL
9766167 490408  3   abc2'
;

select N'insert into '
        + @tbl_name             -- table name
        + ' VALUES(' 
        + replace               -- replace 'NULL' by NULL
          ( '''' 
             + replace          -- surround values by quotes 'value1','value2'...
               (    value
               ,    @dlm        -- Delimiter: HT = char(9) = HorizontalTab
               ,    ''','''
               ) 
             + ''''
          , '''NULL'''  
          , 'NULL'      
          )                                              
        + ');' as insertquery
--into #t 
from fn_split_string            -- insert Line per Row into table
     (  replace                 -- replace CR + LF by LF  (CR - Carriage Return, LF - Line Feed)
        (   @tbl                -- Paste Table Values here (from excel for instance)
        , char(13)+char(10)     -- CR + LF
        , char(10)              -- LF
        )
     ,char(10)
     ) 
where len(value)>0              -- skip empty rows

查询 select into 临时 table:

-- PURPOSE: create temp table with values pasted from Excel (or any other CSV source)
-- NB! Script do NOT write any ifo to any table
-- to perform insert please copy/paste script output SelectInto column and execute
-- NB! Current script works only for tables with RowNumbers < 1000

declare @tmp_tbl_name   nvarchar(max)   = N'#t';    -- Destination Table Name 
declare @tmp_clm_name   nvarchar(max)   = NULL;     -- comma separated COLUMN Names; if NOT defined (NULL) - takes from 1st data row
declare @dlm            nvarchar(128)   = char(9);  -- Delimiter: HT = char(9) = HorizontalTab
declare @eol            nvarchar( 2 )   = N'
';                                                  -- EndOfLine
declare @tbl            nvarchar(max)   =           -- Paste Table Values here (from excel for instance)
N'CopyPasteExcelTableHere'
;

------------------------------------------------------------------------------------------------------------
declare @FirstRow  nvarchar(max); 
declare @LastRow   nvarchar(max); 

SET @tbl =     REPLACE               -- replace EndOfLine by LF  (CR - Carriage Return, LF - Line Feed)
                ( @tbl                  -- Paste Table Values here (from excel for instance)
                , @eol                  -- EndOfLine
                , char(10)              -- LF
                )
;

IF @tmp_clm_name is NULL    --> 1st row contains column names
    BEGIN
        SET @tmp_clm_name = left(@tbl, charindex(char(10), @tbl)-1);
        SET @tbl          = stuff(@tbl, 1, len(@tmp_clm_name)+1, '');
        SET @tmp_clm_name = '[' + REPLACE(@tmp_clm_name, @dlm, '],[') + ']';
    END
;

SET @FirstRow  = N'IF OBJECT_ID(''tempdb..'+@tmp_tbl_name+''') IS NOT NULL DROP TABLE '+ @tmp_tbl_name + ';'
        + @eol + N'-- select '+ @tmp_clm_name+' from #t;'
        + @eol + N'SELECT * INTO ' +  @tmp_tbl_name + N' FROM '
        + @eol + N'(VALUES '                            
;

SET @LastRow    = N') t('+ @tmp_clm_name +');'        
;

;with v as
(  select  --row_number()  over(order by insertquery),            
             ',(' 
            + replace               -- replace 'NULL' by NULL
              ( '''' 
                 + replace          -- surround values by quotes 'value1','value2'...
                   (    value
                   ,    @dlm        -- Delimiter: HT = char(9) = HorizontalTab
                   ,    ''','''
                   ) 
                 + ''''
              , '''NULL'''  
              , 'NULL'      
              )                                              
            + ')' as insertvalues
    --into #t 
    from  string_split(@tbl, char(10))   -- insert Line per Row into table
    where len(value)>0                   -- skip empty rows
),
rv as -- adding RowID column (have to identify 1st row to remove 1st character)
(   select (ROW_NUMBER() OVER(ORDER BY insertvalues)) as RowID, *  
    from v
)
          select 1 as RowID                  , @FirstRow as SelectInto 
union all select 1 +  RowID                  , case when RowID=1 then stuff(insertvalues,1,1,' ') else insertvalues end from rv
union all select 2 +(select count(*) from rv), @LastRow 
order by RowID

SELECT INTO 的代码段:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
    <CodeSnippet Format="1.0.0">
        <Header>
            <Title>SelectTable</Title>    <!--SelectTable.snippet -copy/paste for filename-->
            <Shortcut></Shortcut>
            <Description>Prepare Copy/Paste Excel data for exporting to temp table</Description>
            <Author>Denis Sipchenko</Author>
            <SnippetTypes>
                <SnippetType>SurroundsWith</SnippetType>    <!--SurroundsWith/Expansion-->
            </SnippetTypes>
        </Header>
        <Snippet>
            <Declarations>
                <Literal> <ID>t_name</ID>     <Default>#t</Default>                            <ToolTip>Destination Table Name</ToolTip>                            </Literal>
                <Literal> <ID>col_nm</ID>     <Default>NULL</Default>                          <ToolTip>comma separated COLUMN Names</ToolTip>                      </Literal>
                <Literal> <ID>selected</ID>   <Default>CopyPasteExcelTableHere</Default>       <ToolTip>copy/paste Excel data here</ToolTip>                        </Literal>
                <Literal> <ID>delimiter</ID>  <Default>char(9)</Default>                       <ToolTip>Column Delimiter: HT = char(9) = HorizontalTab</ToolTip>    </Literal>
                <Literal> <ID>eol</ID>  <Default>N'
'</Default>                       <ToolTip>EndOfLine</ToolTip>    </Literal>
            </Declarations>
            <Code Language="SQL">
                <![CDATA[-- PURPOSE: create temp table with values pasted from Excel (or any other CSV source)
-- NB! Script do NOT write any ifo to any table
-- to perform insert please copy/paste script output SelectInto column and execute
-- NB! Current script works only for tables with RowNumbers < 1000

declare @tmp_tbl_name   nvarchar(max)   = N'$t_name$';     -- Destination Table Name 
declare @tmp_clm_name   nvarchar(max)   = $col_nm$;     -- comma separated COLUMN Names; if NOT defined (NULL) - takes from 1st data row
declare @tbl            nvarchar(max)   =           -- Paste Table Values here (from excel for instance)
N'$selected$'
;
declare @dlm            nvarchar(128)   = $delimiter$;  -- Delimiter: HT = char(9) = HorizontalTab
declare @eol            nvarchar( 2 )   = N'
';                                                  -- EndOfLine

------------------------------------------------------------------------------------------------------------
declare @FirstRow  nvarchar(max); 
declare @LastRow   nvarchar(max); 

SET @tbl =     REPLACE               -- replace EndOfLine by LF  (CR - Carriage Return, LF - Line Feed)
                ( @tbl                  -- Paste Table Values here (from excel for instance)
                , @eol                  -- EndOfLine
                , char(10)              -- LF
                )
;

IF @tmp_clm_name is NULL    --> 1st row contains column names
    BEGIN
        SET @tmp_clm_name = left(@tbl, charindex(char(10), @tbl)-1);
        SET @tbl          = stuff(@tbl, 1, len(@tmp_clm_name)+1, '');
        SET @tmp_clm_name = '[' + REPLACE(@tmp_clm_name, @dlm, '],[') + ']';
    END
;

SET @FirstRow  = N'IF OBJECT_ID(''tempdb..'+@tmp_tbl_name+''') IS NOT NULL DROP TABLE '+ @tmp_tbl_name + ';'
        + @eol + N'-- select '+ @tmp_clm_name+' from $t_name$;'
        + @eol + N'SELECT * INTO ' +  @tmp_tbl_name + N' FROM '
        + @eol + N'(VALUES '                            
;

SET @LastRow    = N') t('+ @tmp_clm_name +');'        
;

;with v as
(  select  --row_number()  over(order by insertquery),            
             ',(' 
            + replace               -- replace 'NULL' by NULL
              ( '''' 
                 + replace          -- surround values by quotes 'value1','value2'...
                   (    value
                   ,    @dlm        -- Delimiter: HT = char(9) = HorizontalTab
                   ,    ''','''
                   ) 
                 + ''''
              , '''NULL'''  
              , 'NULL'      
              )                                              
            + ')' as insertvalues
    --into #t 
    from  string_split(@tbl, char(10))   -- insert Line per Row into table
    where len(value)>0                   -- skip empty rows
),
rv as -- adding RowID column (have to identify 1st row to remove 1st character)
(   select (ROW_NUMBER() OVER(ORDER BY insertvalues)) as RowID, *  
    from v
)
          select 1 as RowID                  , @FirstRow as SelectInto 
union all select 1 +  RowID                  , case when RowID=1 then stuff(insertvalues,1,1,' ') else insertvalues end from rv
union all select 2 +(select count(*) from rv), @LastRow 
order by RowID
$end$
]]>
            </Code>
        </Snippet>
    </CodeSnippet>
</CodeSnippets>

屏幕