sql >> データベース >  >> Database Tools >> SSMS

SSMS:同じSQLスクリプトの複数の結果セットをExcelの別々のタブに自動的に保存しますか?

    Oleオートメーション手順を許可できる場合は、このソリューションを次のように使用できます。 @OutputFileNameパラメーターを使用しないストアドプロシージャを作成し、bcpを使用してバイナリコンテンツをファイルに保存することもできます(出力の先頭にデータを追加せずにバイナリコンテンツをエクスポートするフォーマットファイルを使用)。

    これは、必要なテキストまたは数値の書式を使用してExcelスプレッドシートを簡単に生成できないことへの不満から書きました。手順AddFileToArchiveは、入力ファイルの内容を含むzipアーカイブを生成し、GetExcelSpreadsheetDataによって内部的に使用されます。

    GetExcelSpreadsheetDataは、1つ以上の一時テーブルのワークシートを生成し、準拠したopenxmlワークブックを出力します。ワークシートには太字の列見出しがあります。拡張子が.zipのファイルを出力すると、他の.xlsxファイルと同様の内部ファイルの内容が表示されますが、データは共有値ではなくインラインで内部的に保存されます。 「autofilter」オプションを追加することで、ワークシートを自動フィルタリングできます。

    現在、日付の書式設定はdd / mm / yyyyにハードコーディングされていますが、次の行を変更することで変更できます。

        <numFmt formatCode="dd/mm/yyyy\ hh:mm" numFmtId="165"/>
        <numFmt formatCode="hh:mm" numFmtId="166"/>
        <numFmt formatCode="dd/mm/yyyy" numFmtId="167"/>
    

    コメント不足でごめんなさい。

    SQL Server CheckSumはCRCを計算しますか?そうでない場合、MS SQLで任意のvarchar列のCRCを計算するにはどうすればよいですか? SQLServer2012または2014で実行された場合に使用されるGetCRC32コードの場合。

    下部の使用例。

    うまくいけば、これがお役に立てば幸いです。この手順は、SQLServer2008R2以前では機能しません。

    /****** Object:  UserDefinedFunction [dbo].[GetCRC32]    Script Date: 23/10/2020 4:52:31 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    create function [dbo].[GetCRC32](@Text varchar(max)) returns binary(4) as
    begin
        declare
            @crc bigint = 0xFFFFFFFF
            ,@Lookup varbinary(2048) = 0x0000000077073096EE0E612C990951BA076DC419706AF48FE963A5359E6495A30EDB883279DCB8A4E0D5E91E97D2D98809B64C2B7EB17CBDE7B82D0790BF1D911DB710646AB020F2F3B9714884BE41DE1ADAD47D6DDDE4EBF4D4B55183D385C7136C9856646BA8C0FD62F97A8A65C9EC14015C4F63066CD9FA0F3D638D080DF53B6E20C84C69105ED56041E4A26771723C03E4D14B04D447D20D85FDA50AB56B35B5A8FA42B2986CDBBBC9D6ACBCF94032D86CE345DF5C75DCD60DCFABD13D5926D930AC51DE003AC8D75180BFD0611621B4F4B556B3C423CFBA9599B8BDA50F2802B89E5F058808C60CD9B2B10BE9242F6F7C8758684C11C1611DABB6662D3D76DC419001DB710698D220BCEFD5102A71B1858906B6B51F9FBFE4A5E8B8D4337807C9A20F00F9349609A88EE10E98187F6A0DBB086D3D2D91646C97E6635C016B6B51F41C6C6162856530D8F262004E6C0695ED1B01A57B8208F4C1F50FC45765B0D9C612B7E9508BBEB8EAFCB9887C62DD1DDF15DA2D498CD37CF3FBD44C654DB261583AB551CEA3BC0074D4BB30E24ADFA5413DD895D7A4D1C46DD3D6F4FB4369E96A346ED9FCAD678846DA60B8D044042D7333031DE5AA0A4C5FDD0D7CC95005713C270241AABE0B1010C90C20865768B525206F85B3B966D409CE61E49F5EDEF90E29D9C998B0D09822C7D7A8B459B33D172EB40D81B7BD5C3BC0BA6CADEDB883209ABFB3B603B6E20C74B1D29AEAD547399DD277AF04DB261573DC1683E3630B1294643B840D6D6A3E7A6A5AA8E40ECF0B9309FF9D0A00AE277D079EB1F00F93448708A3D21E01F2686906C2FEF762575D806567CB196C36716E6B06E7FED41B7689D32BE010DA7A5A67DD4ACCF9B9DF6F8EBEEFF917B7BE4360B08ED5D6D6A3E8A1D1937E38D8C2C44FDFF252D1BB67F1A6BC57673FB506DD48B2364BD80D2BDAAF0A1B4C36034AF641047A60DF60EFC3A867DF55316E8EEF4669BE79CB61B38CBC66831A256FD2A05268E236CC0C7795BB0B4703220216B95505262FC5BA3BBEB2BD0B282BB45A925CB36A04C2D7FFA7B5D0CF312CD99E8B5BDEAE1D9B64C2B0EC63F226756AA39C026D930A9C0906A9EB0E363F720767850500571395BF4A82E2B87A147BB12BAE0CB61B3892D28E9BE5D5BE0D7CDCEFB70BDBDF2186D3D2D4F1D4E24268DDB3F81FDA836E81BE16CDF6B9265B6FB077E118B7477788085AE6FF0F6A7066063BCA11010B5C8F659EFFF862AE69616BFFD3166CCF45A00AE278D70DD2EE4E0483543903B3C2A7672661D06016F74969474D3E6E77DBAED16A4AD9D65ADC40DF0B6637D83BF0A9BCAE53DEBB9EC547B2CF7F30B5FFE9BDBDF21CCABAC28A53B3933024B4A3A6BAD03605CDD7069354DE572923D967BFB3667A2EC4614AB85D681B022A6F2B94B40BBE37C30C8EA15A05DF1B2D02EF8D
            ,@LenText int = len(@Text);
     
            with x as (
                select '' as Id
                union all
                select '' as Id from x
            )
            ,y as (select top (cast(ceiling(sqrt(sqrt(@LenText))) as int)) '' as id from x)
            ,v as (
                select top (@LenText) row_number() over (order by (select null)) as ID
                from y cross join y as y2 cross join y as y3 cross join y as y4
            )
        SELECT @crc = (@crc / 256) ^ Substring(@Lookup, ((@crc & 0xFF) ^ Ascii(Substring(@Text, V.ID, 1))) * 4 + 1, 4)
        FROM  V
     
        SET @crc = [email protected];
     
        return cast(reverse(cast(@crc as varbinary(4))) as binary(4));
    end
    GO
    /****** Object:  UserDefinedFunction [dbo].[StringSplit2]    Script Date: 23/10/2020 4:52:32 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    create function [dbo].[StringSplit2] (@StringToSplit varchar(max), @Seperator char(1)) returns table
    as
    return (
        with Split as (
            select
                1 as ValueOrder
                ,cast(1 as int) as ValueStartPos
                ,cast(charindex(@Seperator, @StringToSplit + @Seperator) as int) as ValueEndPos
            union all
            select
                ValueOrder + 1 as ValueOrder
                ,ValueEndPos + 1 as ValueStartPos
                ,cast(charindex(@Seperator, @StringToSplit + @Seperator, ValueEndPos + 1) as int) as ValueEndPos
            from Split
            where ValueEndPos <> 0
        )
        select
            ValueOrder
            ,substring(@StringToSplit, ValueStartPos, case when ValueEndPos = 0 then 0 else ValueEndPos-ValueStartPos end) as value
        from Split
        where ValueEndPos <> 0
    )
    GO
    /****** Object:  StoredProcedure [dbo].[AddFileToArchive]    Script Date: 23/10/2020 4:52:32 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    create procedure [dbo].[AddFileToArchive](@FileName varchar(max), @FileContents varbinary(max), @ArchiveData varbinary(max) output, @ArchiveInfo binary(10) output)
    as
    begin
        set nocount on;
     
        declare
            @LocalFileHeaderSignature binary(4) = 0x504b0304
            ,@CentralDirectoryFileHeaderSignature binary(4) = 0x504b0102
            ,@EndOfCentralDirectorySignature binary(4) = 0x504b0506
            ,@VersionNeededToExtract binary(2) = 0x1400
            ,@VersionMadeBy binary(2) = 0x1400
            ,@GeneralPurposeBitFlag binary(2) = 0x0000
            ,@CompressionMethod binary(2) = 0x0000--0x0800
            ,@CompressionMethodDeflate binary(2) = 0x0800
            ,@FileLastModificationTime binary(2) = 0xA351 -- dummy time
            ,@FileLastModificationDate binary(2) = 0x6250 -- dummy date
            ,@currentDateTime datetime = getdate()
            ,@CRC32 binary(4)
            ,@CompressedSize int
            ,@UncompressedSize int
            ,@FileNameLength smallint
            ,@ExtraFieldLength smallint = 0
            ,@FileCommentLength smallint = 0
            ,@CommentLength smallint = 0
            ,@NumberOfThisDisk smallint = 0
            ,@DiskNumberWhereFileStarts smallint = 0
            ,@InternalFileAttributes binary(2) = 0x0100
            ,@ExternalFileAttributes binary(4) = 0x20000000
            ,@LocalFileRecordLength int
     
            ,@LocalFileRecord varbinary(max)
            ,@CompressedFileContents varbinary(max)
            ,@LenCompressedFileContents int
            ,@FileCRC32 binary(4)
            ,@OffsetOfStartOfCentralDirectory int
     
            ,@CentralDirectoryRecord varbinary(max)
            ,@EndOfCentralDirectoryRecord varbinary(max)
                       
            ,@sql nvarchar(max)
            ,@OtherFileCount smallint
            ,@FileOffset int
            ,@SizeOfCentralDirectory int;
     
        set @OtherFileCount = IsNull(cast(SubString(@ArchiveInfo, 1, 2) as smallint), 0);
        set @FileOffset = IsNull(cast(SubString(@ArchiveInfo, 3, 4) as int), 0);
        set @SizeOfCentralDirectory = IsNull(cast(SubString(@ArchiveInfo, 7, 4) as int), 0);
     
        set @FileLastModificationTime = cast(reverse(cast((datepart(ss, @currentDateTime) / 2) | (32 * datepart(mi, @currentDateTime)) | (2048 * datepart(hh, @currentDateTime)) as binary(2))) as binary (2));
        set @FileLastModificationDate = cast(reverse(cast((datepart(dd, @currentDateTime)) | (32 * datepart(mm, @currentDateTime)) | (512 * (datepart(yy, @currentDateTime) - 1980)) as binary(2))) as binary (2));
     
        -- for SQL Server 2016 or higher compress the file contents
        if cast(serverproperty('ProductMajorVersion') as int) > 12 -- SQL Server 2016+
        begin
            exec sp_executesql
                @stmt = N'set @CompressedFileContents = compress(@FileContents)'
                ,@params = N'@FileContents varbinary(max), @CompressedFileContents varbinary(max) output'
                ,@CompressedFileContents = @CompressedFileContents output
                ,@FileContents = @FileContents;
            set @FileCRC32 = substring(@CompressedFileContents, len(@CompressedFileContents) - 7, 4);
            set @CompressionMethod = @CompressionMethodDeflate;
        end
        else
        begin
            set @CompressedFileContents = 0x00000000000000000000 + @FileContents + 0x0000000000000000;
            exec sp_executesql
                @stmt = N'set @FileCRC32 = dbo.GetCRC32(@FileContents)'
                ,@params = N'@FileContents varbinary(max), @FileCRC32 binary(4) output'
                ,@FileContents = @FileContents
                ,@FileCRC32 = @FileCRC32 output;
        end;
     
        set @LenCompressedFileContents = len(@CompressedFileContents);
        set @CompressedSize = @LenCompressedFileContents - 18;
        set @UncompressedSize = len(@FileContents);
     
        set @FileNameLength = len(@FileName);
     
        set @LocalFileRecord =
            @LocalFileHeaderSignature
            [email protected]
            [email protected]
            [email protected]
            [email protected]
            [email protected]
            [email protected]
            +cast(reverse(cast(@CompressedSize as binary(4))) as binary(4))
            +cast(reverse(cast(@UncompressedSize as binary(4))) as binary(4))
            +cast(reverse(cast(@FileNameLength as binary(2))) as binary(2))
            +cast(reverse(cast(@ExtraFieldLength as binary(2))) as binary(2))
            +cast(@FileName as varbinary(max))
            +substring(@CompressedFileContents, 11, @LenCompressedFileContents - 18);
     
        set @CentralDirectoryRecord =
            @CentralDirectoryFileHeaderSignature
            [email protected]
            [email protected]
            [email protected]
            [email protected]
            [email protected]
            [email protected]
            [email protected]
            +cast(reverse(cast(@CompressedSize as binary(4))) as binary(4))
            +cast(reverse(cast(@UncompressedSize as binary(4))) as binary(4))
            +cast(reverse(cast(@FileNameLength as binary(2))) as binary(2))
            +cast(reverse(cast(@ExtraFieldLength as binary(2))) as binary(2))
            +cast(reverse(cast(@FileCommentLength as binary(2))) as binary(2))
            +cast(reverse(cast(@DiskNumberWhereFileStarts as binary(2))) as binary(2))
            [email protected]
            [email protected]
            +cast(reverse(cast(@FileOffset as binary(4))) as binary(4))
            +cast(@FileName as varbinary(max));
     
        set @SizeOfCentralDirectory = @SizeOfCentralDirectory + len(@CentralDirectoryRecord);
        set @LocalFileRecordLength= len(@LocalFileRecord)
        set @OffsetOfStartOfCentralDirectory = @FileOffset + @LocalFileRecordLength;
     
        set @EndOfCentralDirectoryRecord =
            @EndOfCentralDirectorySignature
            +cast(reverse(cast(@NumberOfThisDisk as binary(2))) as binary(2))
            +cast(reverse(cast(@NumberOfThisDisk as binary(2))) as binary(2)) -- Disk where central directory starts
            +cast(reverse(cast(@OtherFileCount + cast(1 as smallint) as binary(2))) as binary(2)) -- Number of central directory records on this disk
            +cast(reverse(cast(@OtherFileCount + cast(1 as smallint) as binary(2))) as binary(2)) -- Total number of central directory records
            +cast(reverse(cast(@SizeOfCentralDirectory as binary(4))) as binary(4))
            +cast(reverse(cast(@OffsetOfStartOfCentralDirectory as binary(4))) as binary(4))
            +cast(reverse(cast(@CommentLength as binary(2))) as binary(2))
     
        if @ArchiveInfo is null
            set @ArchiveData = @LocalFileRecord + @CentralDirectoryRecord + @EndOfCentralDirectoryRecord
        else
            set @ArchiveData =
                SubString(@ArchiveData, 1, @FileOffset) + @LocalFileRecord
                +SubString(@ArchiveData, @FileOffset + 1, @SizeOfCentralDirectory - len(@CentralDirectoryRecord)) + @CentralDirectoryRecord
                [email protected];
     
        set @ArchiveInfo =
            cast(@OtherFileCount + 1 as binary(2))
            + cast(@FileOffset + @LocalFileRecordLength as binary(4))
            + cast(@SizeOfCentralDirectory as binary(4));
     
    --             select @ArchiveInfo as ArchiveInfo, @LocalFileRecord as LocalFileRecord,@CentralDirectoryRecord as CentralDirectoryRecord, @EndOfCentralDirectoryRecord as EndOfCentralDirectoryRecord
        return;
    end
    GO
    /****** Object:  StoredProcedure [dbo].[GetExcelSpreadsheetData]    Script Date: 23/10/2020 4:52:32 PM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
     
    CREATE      procedure [dbo].[GetExcelSpreadsheetData](@SheetName varchar(31) = null, @Worksheets varchar(max) = null, @WorkbookData varbinary(max) = null output, @OutputFileName nvarchar(500) = null)
    as
        set nocount on;
     
    declare
        @LocalFileRecords varbinary(max)
        ,@CentralDirectoryRecords varbinary(max)
        ,@EndOfCentralDirectoryRecord varbinary(max)
        ,@OtherFileCount smallint
        ,@FileOffset int
        ,@SizeOfCentralDirectory int
        ,@NumberOfWorksheets smallint
        ,@CurrentWorksheet smallint = 1
        ,@sql nvarchar(max) = N''
        ,@rowcountsql nvarchar(max)
        ,@rowcount int
        ,@colcount int
        ,@datatable varchar(100)
        ,@RowDataXML nvarchar(max)
        ,@SelectOutput bit = 0
        ,@ArchiveInfo binary(10)
        ,@WorksheetFileName varchar(50)
        ,@ObjectToken int
        ,@AutoFilterXML nvarchar(max) = N''
     
        ,@_Content_Types__xml__sheets nvarchar(max)
        ,@_Content_Types__xml varbinary(max)
        ,@Workbook_xml_temp nvarchar(max)
        ,@Workbook_xml varbinary(max)
        ,@_Rels_workbook_xml_rels varbinary(max)
        ,@styles_xml varbinary(max) = cast(N'<?xml version="1.0" encoding="utf-16"?>
    <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
      <numFmts count="3">
        <numFmt formatCode="dd/mm/yyyy\ hh:mm" numFmtId="165"/>
        <numFmt formatCode="hh:mm" numFmtId="166"/>
        <numFmt formatCode="dd/mm/yyyy" numFmtId="167"/>
      </numFmts>
      <fonts count="7">
        <font>    <sz val="11"/>            <name val="Calibri"/><family val="2" /><scheme val="minor" /></font>
        <font>    <sz val="11"/><color rgb="FFFF0000" /><name val="Calibri"/><family val="2" /><scheme val="minor" /></font>
        <font><b/><sz val="11"/>            <name val="Calibri"/><family val="2" /><scheme val="minor" /></font>
        <font><i/><sz val="11"/>            <name val="Calibri"/><family val="2" /><scheme val="minor" /></font>
        <font>    <sz val="11"/><color rgb="FF0070C0" /><name val="Calibri"/><family val="2" /><scheme val="minor" /></font>
        <font>    <sz val="20"/>            <name val="Calibri"/><family val="2" /><scheme val="minor" /></font>
        <font>    <sz val="11"/>            <name val="Courier"/><family val="3" />       </font>
      </fonts>
      <fills count="2">
        <fill>
          <patternFill patternType="none" />
        </fill>
        <fill>
          <patternFill patternType="gray125" />
        </fill>
      </fills>
      <borders count="1">
        <border>
          <left />
          <right />
          <top />
          <bottom />
          <diagonal />
        </border>
      </borders>
      <cellStyleXfs count="1">
        <xf numFmtId="0" fontId="0" fillId="0" borderId="0" />
      </cellStyleXfs>
      <cellXfs count="10">
        <xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0" />
        <xf numFmtId="0" fontId="2" fillId="0" borderId="0" xfId="0" applyFont="1" />
        <xf numFmtId="0" fontId="3" fillId="0" borderId="0" xfId="0" applyFont="1" />
        <xf numFmtId="0" fontId="4" fillId="0" borderId="0" xfId="0" applyFont="1" />
        <xf numFmtId="0" fontId="1" fillId="0" borderId="0" xfId="0" applyFont="1" />
        <xf numFmtId="0" fontId="5" fillId="0" borderId="0" xfId="0" applyFont="1" />
        <xf numFmtId="0" fontId="6" fillId="0" borderId="0" xfId="0" applyFont="1" />
        <xf numFmtId="165" borderId="0" fillId="0" fontId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="166" borderId="0" fillId="0" fontId="0" xfId="0" applyNumberFormat="1"/>
        <xf numFmtId="167" borderId="0" fillId="0" fontId="0" xfId="0" applyNumberFormat="1"/>
      </cellXfs>
      <cellStyles count="1">
        <cellStyle name="Standard" xfId="0" builtinId="0" />
      </cellStyles>
      <dxfs count="0" />
      <tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleLight16" />
    </styleSheet>' as varbinary(max))
     
        ,@worksheet_xml varbinary(max)
     
        ,@_rels_rels varbinary(max) = cast(N'<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
    <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
      <Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="workbook.xml"/>
    </Relationships>' as varbinary(max));
     
        -- if Worksheets is not specified, set @Worksheets to @SheetName + / + #data
        if @Worksheets is null-- @SheetName is not null and @Worksheets is null
            set @Worksheets = IsNull(@SheetName, 'Sheet1') + '/#data';
     
        -- if a non-null value is passed in @WorkbookData, the output should be set in the optional output parameter @WorkbookData
        -- if a null or no value is passed in @WorkbookData, the output will be selected at the end of the procedure
        if @WorkbookData is null and @OutputFileName is null
            set @SelectOutput = 1
        else
            set @WorkbookData = null;
     
        select
            Worksheet.ValueOrder as WorksheetNumber
            ,WorksheetTable.ValueOrder as ColumnNumber
            ,WorksheetTable.value
            ,WorksheetTableOptions.ValueOrder as WorksheetOptionNumber
            ,WorksheetTableOptions.value as WorksheetOption
        into #WorksheetConfig
        from dbo.StringSplit2(@Worksheets, '|') as Worksheet
        cross apply dbo.StringSplit2(Worksheet.value, '/') as WorksheetTable
        cross apply dbo.StringSplit2(WorksheetTable.value, '~') as WorksheetTableOptions;
     
        select
            @NumberOfWorksheets = max(WorksheetNumber)
        from #WorksheetConfig;
                       
        -- xml for @Workbook_xml
        with xmlnamespaces (
           'http://schemas.openxmlformats.org/officeDocument/2006/relationships' as r
           ,default 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'
        )
        select @Workbook_xml_temp = (
            select
                Worksheet.value as [sheet/@name]
                ,Worksheet.WorksheetNumber as [sheet/@sheetId]
                ,'rId' + cast(Worksheet.WorksheetNumber + 1 as varchar) as [sheet/@r:id]
            from #WorksheetConfig Worksheet
            where ColumnNumber = 1
            for xml path('sheets'), root('workbook')
        );
     
        set @Workbook_xml = cast(Replace(@Workbook_xml_temp, '</sheets><sheets>', '') as varbinary(max));
                   
        -- xml for @_Content_Types__xml
        select @_Content_Types__xml__sheets = (
            select
                '/sheet' + cast(Worksheet.WorksheetNumber as varchar) + '.xml' as [@PartName]
                ,'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml' as [@ContentType]
            from #WorksheetConfig Worksheet
            where ColumnNumber = 1
            for xml path('Override')
        );
     
        -- xml for @_Rels_workbook_xml_rels
        with xmlnamespaces (
           default 'http://schemas.openxmlformats.org/package/2006/relationships'
        )
        ,x as (
            select
                'rId1' as [@Id]
                ,'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles' as [@Type]
                ,'styles.xml' as [@Target]
            union all
            select
                'rId' + cast(Worksheet.WorksheetNumber + 1 as varchar) as [@Id]
                ,'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet' as [@Type]
                ,'sheet' + cast(Worksheet.WorksheetNumber as varchar) + '.xml' as [@Target]
            from #WorksheetConfig Worksheet
            where ColumnNumber = 1
        )
        select @_Rels_workbook_xml_rels = cast((
            select
                *
            from x
            for xml path('Relationship'), root('Relationships')
        ) as varbinary(max));
     
        set @_Content_Types__xml = cast(N'<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
    <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
      <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
      <Override PartName="/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
      <Override PartName="/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
    ' + @_Content_Types__xml__sheets + '
    </Types>' as varbinary(max));
     
    exec dbo.AddFileToArchive
        @FileName = '[Content_Types].xml'
        ,@FileContents = @_Content_Types__xml
        ,@ArchiveData = @WorkbookData output
        ,@ArchiveInfo = @ArchiveInfo output;
     
    exec dbo.AddFileToArchive
        @FileName = '_rels/.rels'
        ,@FileContents = @_rels_rels
        ,@ArchiveData = @WorkbookData output
        ,@ArchiveInfo = @ArchiveInfo output;
     
    exec dbo.AddFileToArchive
        @FileName = '_rels/workbook.xml.rels'
        ,@FileContents = @_Rels_workbook_xml_rels
        ,@ArchiveData = @WorkbookData output
        ,@ArchiveInfo = @ArchiveInfo output;
     
    exec dbo.AddFileToArchive
        @FileName = 'workbook.xml'
        ,@FileContents = @workbook_xml
        ,@ArchiveData = @WorkbookData output
        ,@ArchiveInfo = @ArchiveInfo output;
     
    exec dbo.AddFileToArchive
        @FileName = 'styles.xml'
        ,@FileContents = @styles_xml
        ,@ArchiveData = @WorkbookData output
        ,@ArchiveInfo = @ArchiveInfo output;
     
    while @CurrentWorksheet <= @NumberOfWorksheets
    begin
        set @sql = '';
     
        select
            @datatable = value
        from #WorksheetConfig
        where WorksheetNumber = @CurrentWorksheet
        and ColumnNumber = 2;
                   
        select @sql +=
        ',''' + rtrim(case when column_id > 26 then char(64 + ((column_id -1) / 26)) + char(65 + ((column_id -1) % 26)) else char(64 + column_id) end) + ''' + cast(__r__ as varchar) as [c/@r]'
        + case when sc.system_type_id in (40, 41, 42, 43, 48, 52, 56, 58, 61, 62, 104, 106, 108, 127) then '' else ',''inlineStr'' as [c/@t]' end -- non text data types
        + case
            when sc.system_type_id in (42, 43, 58, 61) then ',7 as [c/@s]' -- datetime2, datetimeoffset smalldatetime, datetime
            when sc.system_type_id in (41) then ',8 as [c/@s]' -- time
            when sc.system_type_id in (40) then ',9 as [c/@s]' -- date
            else ''
        end -- smalldatetime, datetime, time, date
        + ',' + case
                    when sc.system_type_id in (40, 58, 61) then 'cast(cast(' + quotename(name) + 'as datetime) as float) + case when ''19000301'' > ' + quotename(name) + ' then 1 else 2 end'
                    when sc.system_type_id in (42, 43) then 'cast(cast(cast(' + quotename(name) + ' as date) as datetime) as float) + datepart(hh, ' + quotename(name) + ') / 24.00000 + datepart(mi, ' + quotename(name) + ') / 1440.00000 + datepart(ss, ' + quotename(name) + ') / 86400.00000 + datepart(ms, ' + quotename(name) + ') / 86400000.00000 + case when ''19000301'' > ' + quotename(name) + ' then 1 else 2 end'
                    when sc.system_type_id in (41) then 'cast(cast(' + quotename(name) + ' as datetime) as float)' else quotename(name)
                end
        + case when sc.system_type_id in (40, 41, 42, 43, 48, 52, 56, 58, 61, 62, 104, 106, 108, 127) then ' as [c/v]' else ' as [c/is/t]' end
        + ','''''
        from tempdb.sys.columns sc
        where object_id = object_id('tempdb.dbo.' + @datatable)
        order by column_id;
     
        set @sql = right(@sql, len(@sql) - 1);
     
        set @sql =
        'select @xml = (select(cast((
                select
                    1 as [@r]
                    ,(
                        select
                            rtrim(case when column_id > 26 then char(64 + ((column_id -1) / 26)) + char(65 + ((column_id -1) % 26)) else char(64 + column_id) end) + ''1'' as [c/@r]
                            ,1 as [c/@s]
                            ,''inlineStr'' as [c/@t]
                            ,name as [c/is/t]
                        from tempdb.sys.columns sc
                        where object_id = object_id(''' + case when left(@datatable, 1) = '#' then 'tempdb.dbo.' else '' end + Replace(@datatable, '''', '''''') + ''')
                        order by column_id
                        for xml path(''''), type
                    )
                    from (select 1 as c1) x
                    for xml path(''row''))
        as nvarchar(max))))
        +
        (select(IsNull(cast((
                select
                    __r__ as [@r]
                    ,(
                        select
        ' + @sql + '
                        for xml path(''''), type
                    )
                    from (select row_number() over (order by (select 1)) + 1 as __r__, * from ' + Replace(@datatable, '''', '''''') + ') d
                    for xml path(''row''))
        as nvarchar(max)), '''')));';
     
        exec sp_executesql @stmt = @sql, @params = N'@xml nvarchar(max) output', @xml = @RowDataXML output;
     
        if exists (select * from #WorksheetConfig where WorksheetNumber = @CurrentWorksheet and ColumnNumber = 3 and WorksheetOption = 'autofilter')
        begin
            set @rowcountsql = N'select @rowcount = count(*) + 1 from ' + @datatable;
            exec sp_executesql @stmt = @rowcountsql, @params = N'@rowcount int output', @rowcount = @rowcount output;
     
            select
                @colcount = count(*)
            from tempdb.sys.columns sc
            where object_id = object_id('tempdb.dbo.' + @datatable);
     
            select @AutoFilterXML = N'<autoFilter ref="A1:'
                + rtrim(case when @colcount > 26 then char(64 + ((@colcount -1) / 26)) + char(65 + ((@colcount -1) % 26)) else char(64 + @colcount) end) + cast(@rowcount as nvarchar)
                + '" xr:uid="{' + cast(newid() as nvarchar(36)) + '}"/>';
        end;
     
        set @worksheet_xml = cast(
        '<?xml version="1.0" encoding="UTF-16" standalone="yes"?><worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision"><sheetData>' + @RowDataXML + '</sheetData>' + @AutoFilterXML + '</worksheet>'
        as varbinary(max));
     
        set @WorksheetFileName = 'sheet' + cast(@CurrentWorksheet as varchar) + '.xml';
        exec dbo.AddFileToArchive
            @FileName = @WorksheetFileName
            ,@FileContents = @worksheet_xml
            ,@ArchiveData = @WorkbookData output
            ,@ArchiveInfo = @ArchiveInfo output;
        set @CurrentWorksheet = @CurrentWorksheet +1;
     
        set @AutoFilterXML = N'';
    end;
     
    if @SelectOutput = 1
        select @WorkbookData as ExcelSpreadsheetData;
     
    if @OutputFileName is not null and (select value_in_use from sys.configurations where name = 'Ole Automation Procedures') = 1
    begin
        exec sp_oacreate 'ADODB.Stream', @ObjectToken output;
        exec sp_oasetproperty @ObjectToken, 'type', 1;
        exec sp_oamethod @ObjectToken, 'open';
        exec sp_oamethod @ObjectToken, 'write', null, @WorkbookData;
        exec sp_oamethod @ObjectToken, 'savetofile', null, @OutputFileName, 2;
        exec sp_oamethod @ObjectToken, 'close';
        exec sp_oadestroy @ObjectToken;
    end;
     
    return;
    GO
    

    使用例:

    select * into #systables from sys.tables;
    select * into #syscolumns from sys.columns;
    select * into #systypes from sys.types;
    
    exec dbo.GetExcelSpreadsheetData
        @Worksheets = 'sys.tables/#systables/autofilter|sys.columns/#syscolumns/autofilter|sys.types/#systypes'
        ,@OutputFileName = 'c:\tmp\ExcelData.xlsx';
    
    drop table #systables;
    drop table #syscolumns;
    drop table #systypes;
    

    編集:これはTSQLで行うのはばかげたことだとコメントする人には同意します。当時は悪い考えのようでしたが、それは私の人生を楽にしてくれます。



    1. SQL Server 2016 Express Management Studioは、新規または既存のテーブルを設計できません

    2. 古い価格の最後のチャンス

    3. PHPを使用して入力SQLクエリをHTMLとしてフォーマットしますか?

    4. phpmyadminを使用してExcelファイルをmysqlデータベースにインポートする方法