it-swarm.com.de

So erstellen Sie eine CSV-Ausgabedatei aus einer gespeicherten Prozedur in SQL Server

Ist es möglich, eine CSV-Datei aus einer gespeicherten Prozedur in SQL Server zu generieren? Ich habe meine gespeicherte Prozedur erstellt und möchte ein Ergebnis als csv speichern. Weiß jemand, wie Sie dies erreichen können?

14
Al Phaba

Ich denke, es ist möglich, den Befehl bcp zu verwenden. Ich bin auch neu bei diesem Befehl, aber ich folgte diesem Link und es hat für mich funktioniert.

3
WowBow

Dieses Skript exportiert Zeilen aus angegebenen Tabellen in das CSV-Format im Ausgabefenster für eine beliebige Tabellenstruktur. Hoffe, das Skript wird für Sie hilfreich sein -

DECLARE 
      @TableName SYSNAME
    , @ObjectID INT

DECLARE [tables] CURSOR READ_ONLY FAST_FORWARD LOCAL FOR 
    SELECT 
          '[' + s.name + '].[' + t.name + ']'
        , t.[object_id]
    FROM (
        SELECT DISTINCT
              t.[schema_id]
            , t.[object_id]
            , t.name
        FROM sys.objects t WITH (NOWAIT)
        JOIN sys.partitions p WITH (NOWAIT) ON p.[object_id] = t.[object_id]
        WHERE p.[rows] > 0
            AND t.[type] = 'U'
    ) t
    JOIN sys.schemas s WITH (NOWAIT) ON t.[schema_id] = s.[schema_id]
    WHERE t.name IN ('<your table name>')

OPEN [tables]

FETCH NEXT FROM [tables] INTO 
      @TableName
    , @ObjectID

DECLARE 
      @SQLInsert NVARCHAR(MAX)
    , @SQLColumns NVARCHAR(MAX)
    , @SQLTinyColumns NVARCHAR(MAX)

WHILE @@FETCH_STATUS = 0 BEGIN

    SELECT 
          @SQLInsert = ''
        , @SQLColumns = ''
        , @SQLTinyColumns = ''

    ;WITH cols AS 
    (
        SELECT 
              c.name
            , datetype = t.name
            , c.column_id
        FROM sys.columns c WITH (NOWAIT)
        JOIN sys.types t WITH (NOWAIT) ON c.system_type_id = t.system_type_id AND c.user_type_id = t.user_type_id
        WHERE c.[object_id] = @ObjectID
            AND c.is_computed = 0
            AND t.name NOT IN ('xml', 'geography', 'geometry', 'hierarchyid')
    )
    SELECT 
          @SQLTinyColumns = STUFF((
            SELECT ', [' + c.name + ']'
            FROM cols c
            ORDER BY c.column_id
            FOR XML PATH, TYPE, ROOT).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
        , @SQLColumns = STUFF((SELECT CHAR(13) +
            CASE 
                WHEN c.datetype = 'uniqueidentifier' 
                    THEN ' + '';'' + ISNULL('''' + CAST([' + c.name + '] AS VARCHAR(MAX)) + '''', ''NULL'')' 
                WHEN c.datetype IN ('nvarchar', 'varchar', 'nchar', 'char', 'varbinary', 'binary') 
                    THEN ' + '';'' + ISNULL('''' + CAST(REPLACE([' + c.name + '], '''', '''''''') AS NVARCHAR(MAX)) + '''', ''NULL'')' 
                WHEN c.datetype = 'datetime'
                    THEN ' + '';'' + ISNULL('''' + CONVERT(VARCHAR, [' + c.name + '], 120) + '''', ''NULL'')' 
                ELSE 
                ' + '';'' + ISNULL(CAST([' + c.name + '] AS NVARCHAR(MAX)), ''NULL'')'
            END
            FROM cols c
            ORDER BY c.column_id
            FOR XML PATH, TYPE, ROOT).value('.', 'NVARCHAR(MAX)'), 1, 10, 'CHAR(13) + '''' +')

    DECLARE @SQL NVARCHAR(MAX) = '    
    SET NOCOUNT ON;
    DECLARE 
          @SQL NVARCHAR(MAX) = ''''
        , @x INT = 1
        , @count INT = (SELECT COUNT(1) FROM ' + @TableName + ')

    IF EXISTS(
        SELECT 1
        FROM tempdb.dbo.sysobjects
        WHERE ID = OBJECT_ID(''tempdb..#import'')
    )
        DROP TABLE #import;

    SELECT ' + @SQLTinyColumns + ', ''RowNumber'' = ROW_NUMBER() OVER (ORDER BY ' + @SQLTinyColumns + ')
    INTO #import
    FROM ' + @TableName + ' 

    WHILE @x < @count BEGIN

        SELECT @SQL = STUFF((
        SELECT ' + @SQLColumns + ' + ''''' + '
        FROM #import 
        WHERE RowNumber BETWEEN @x AND @x + 9
        FOR XML PATH, TYPE, ROOT).value(''.'', ''NVARCHAR(MAX)''), 1, 1, '''')

        PRINT(@SQL)

        SELECT @x = @x + 10

    END'

    EXEC sys.sp_executesql @SQL

    FETCH NEXT FROM [tables] INTO 
          @TableName
        , @ObjectID

END

CLOSE [tables]
DEALLOCATE [tables]

Im Ausgabefenster sehen Sie so etwas (AdventureWorks.Person.Person):

1;EM;0;NULL;Ken;J;Sánchez;NULL;0;92C4279F-1207-48A3-8448-4636514EB7E2;2003-02-08 00:00:00
2;EM;0;NULL;Terri;Lee;Duffy;NULL;1;D8763459-8AA8-47CC-AFF7-C9079AF79033;2002-02-24 00:00:00
3;EM;0;NULL;Roberto;NULL;Tamburello;NULL;0;E1A2555E-0828-434B-A33B-6F38136A37DE;2001-12-05 00:00:00
4;EM;0;NULL;Rob;NULL;Walters;NULL;0;F2D7CE06-38B3-4357-805B-F4B6B71C01FF;2001-12-29 00:00:00
5;EM;0;Ms.;Gail;A;Erickson;NULL;0;F3A3F6B4-AE3B-430C-A754-9F2231BA6FEF;2002-01-30 00:00:00
6;EM;0;Mr.;Jossef;H;Goldberg;NULL;0;0DEA28FD-EFFE-482A-AFD3-B7E8F199D56F;2002-02-17 00:00:00
1
Devart

Habe einen wirklich hilfreichen Link dafür gefunden. Die Verwendung von SQLCMD ist wirklich einfacher, als dies mit einer gespeicherten Prozedur zu lösen

http://www.Excel-sql-server.com/sql-server-export-to-Excel-using-bcp-sqlcmd-csv.htm

1
Al Phaba

Sie können dies mit OPENROWSET tun, wie in dieser Antwort vorgeschlagen. Umbuchung Slogmeister Extrarodinare Antwort:

Verwenden Sie T-SQL

INSERT INTO OPENROWSET ('Microsoft.ACE.OLEDB.12.0','Text;Database=D:\;HDR=YES;FMT=Delimited','SELECT * FROM [FileName.csv]')
SELECT Field1, Field2, Field3 FROM DatabaseName

Es gibt jedoch einige Einschränkungen:

  1. Sie benötigen den Microsoft.ACE.OLEDB.12.0-Anbieter. Der Jet 4.0-Anbieter wird auch funktionieren, aber er ist uralt, also habe ich stattdessen diesen verwendet.

  2. Die CSV-Datei muss bereits vorhanden sein. Wenn Sie Header verwenden (HDR = YES), stellen Sie sicher, dass die erste Zeile der CSV-Datei eine durch Trennzeichen getrennte Liste aller Felder ist.

0
jitin14

Ich habe auch bcp verwendet und ein paar andere hilfreiche Beiträge gefunden, die anderen zugute kommen würden, wenn Sie diesen Thread finden

Verwenden Sie VARCHAR(MAX) nicht als Ihre @sql- oder @cmd-Variable für xp_cmdshell; Du wirst bekommen und Fehler

Msg 214, Ebene 16, Status 201, Prozedur xp_cmdshell, Zeile 1 Prozedur erwartet den Parameter 'command_string' vom Typ 'varchar'.

http://www.sqlservercentral.com/Forums/Topic1071530-338-1.aspx

Verwenden Sie NULLIF, um Leerzeichen für die csv-Datei anstelle von NUL zu erhalten (sichtbar im Hex-Editor oder Notepad ++). Ich habe das in der SELECT-Anweisung für bcp verwendet

Wie kann man machen, dass Microsoft BCP leere Zeichenfolge anstelle eines NUL-Zeichens exportiert?

0
Dwayne Thompson

Um auf eine einheimische Art und Weise zu antworten, die dies schließlich tat, musste alles als Varchar gegossen werden

ALTER PROCEDURE [clickpay].[sp_GetDocuments] 

@Submid bigint

AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
   DECLARE @raw_sql varchar(max)

DECLARE @columnHeader VARCHAR(max)
SELECT @columnHeader = COALESCE(@columnHeader+',' ,'')+ ''''+column_name +'''' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Documents'

DECLARE @ColumnList VARCHAR(max)
SELECT @ColumnList = COALESCE(@ColumnList+',' ,'')+ 'CAST('+column_name +' AS VARCHAR)' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Documents'

SELECT @raw_sql = 'SELECT '+ @columnHeader +' UNION ALL SELECT ' + @ColumnList + ' FROM ' + 'Documents where Submid = ' +  CAST(@Submid AS VARCHAR)

-- Insert statements for procedure here
exec(@raw_sql)
  END
0
MichaelEvanchik