Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从SQL Server中的存储过程生成csv输出文件_Sql_Sql Server_Stored Procedures - Fatal编程技术网

如何从SQL Server中的存储过程生成csv输出文件

如何从SQL Server中的存储过程生成csv输出文件,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,是否可以从SQL Server中的存储过程生成csv文件?我创建了存储过程,我想将一些结果存储为csv,有人知道如何实现这一点吗?此脚本在任何表结构的输出窗口中将指定表中的行导出为csv格式。希望,脚本将对您有所帮助- DECLARE @TableName SYSNAME , @ObjectID INT DECLARE [tables] CURSOR READ_ONLY FAST_FORWARD LOCAL FOR SELECT '[' +

是否可以从SQL Server中的存储过程生成csv文件?我创建了存储过程,我想将一些结果存储为csv,有人知道如何实现这一点吗?

此脚本在任何表结构的输出窗口中将指定表中的行导出为csv格式。希望,脚本将对您有所帮助-

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]

找到了一个非常有用的链接。使用SQLCMD进行此操作比使用存储过程解决此问题更容易


我认为可以使用bcp命令。我也不熟悉这个命令,但我遵循了它,它对我起了作用。

我还使用了bcp,并找到了一些其他有用的帖子,如果找到这个帖子,这些帖子将对其他人有益

不要使用
VARCHAR(MAX)
作为xp\u cmdshell的
@sql
@cmd
变量;你会发现错误

Msg 214,16级,状态201,程序xp\U cmdshell,第1行程序 需要类型为“varchar”的参数“command_string”

使用
NULLIF
获取csv文件的空白,而不是
NUL
(可在十六进制编辑器或记事本++中查看)。我在bcp的
SELECT
语句中使用了它


为了回答一个最终奏效的本地方法,所有东西都必须被铸造为varchar

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

您可以按照本文中的建议使用OPENROWSET来实现这一点。转载答复:

使用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
但是,有两个警告:

  • 您需要提供Microsoft.ACE.OLEDB.12.0提供程序。Jet 4.0提供程序也可以工作,但它很古老,所以我使用了这个

  • .CSV文件必须已经存在。如果使用的是标题(HDR=YES),请确保.CSV文件的第一行是所有字段的分隔列表


  • 我已经试过了,它对我很有效:

    sqlcmd -S servername -E -s~ -W -k1 -Q  "sql query here" > "\\file_path\file_name.csv"
    

    除了下面的答案,我会考虑是否真的想从程序中生成CSV文件。第一个问题是权限:SQL Server服务帐户将需要写入输出文件夹的权限,这可能会导致问题。第二个问题是,通常最好将获取数据与格式化/显示数据分开。让过程生成结果,然后使用外部脚本生成csv文件。通过这种方式,您可以对过程的结果执行许多不同的操作,生成csv文件不是“硬编码”的。请在“结束”之前加4个空格,以便将其包含在代码块中。编辑至少需要6个字符,所以我无法为您进行编辑。请不要使用VARCHAR(MAX)。。。好啊但是我用什么呢?
    sqlcmd -S servername -E -s~ -W -k1 -Q  "sql query here" > "\\file_path\file_name.csv"