如何自动将数据从SQL Server 2012导出到CSV文件?

时间:2015-08-24 16:02:04

标签: csv sql-server-2012 export-to-csv

希望我不要因为问一个简单的问题而烦恼任何人!

我需要将数据从SQL Server 2012表导出到CSV文件。无论何时创建新记录或更新/删除现有记录,都需要每小时完成一次,或者理想情况下,如果可能的话。该表包含我们维护的所有站点的列表。我需要将此CSV文件导出到特定位置,因为来自第三方数据库的API会监视此位置并从那里导入CSV文件。

从SQL中提取的数据是:

Mxmservsite.siteid as Marker_ID, mxmservsite.name as Name, 'SITE' as Group, '3' as Status, 
'' as Notes, mxmservsite.zipcode as Post_Code, 'GB' as Country, '' as Latitude, 
'' as Longitude, '' as Delete
Where dataareaid='ansa'

任何人都有任何线索我怎么能这样做?对不起,我是SQL的新手,还在学习基础知识!我过去曾搜索过类似的问题,但没有发现任何问题。我知道有一个名为BCP的实用程序,但不确定这是否是最好的方式,如果是,那么我如何使用它来运行每小时,或者每当有记录更新/删除/插入?< / p>

干杯

3 个答案:

答案 0 :(得分:1)

这里有一些可以做你想要的事情的权力。只需使用Windows任务计划程序安排它:

function Execute-SQLQuery {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$DbInstance
        ,
        [Parameter(Mandatory = $true)]
        [string]$DbCatalog
        ,
        [Parameter(Mandatory = $true)]
        [string]$Query
        ,
        [Parameter(Mandatory = $false)]
        [int]$CommandTimeoutSeconds = 30 #this is the SQL default
    )
    begin {
        write-verbose "Call to 'Execute-SQLQuery': BEGIN"
        $connectionString = ("Server={0};Database={1};Integrated Security=True;" -f $DbInstance,$DbCatalog)
        $connection = New-Object System.Data.SqlClient.SqlConnection
        $connection.ConnectionString = $connectionString
        $connection.Open()    
    }
    process {
        write-verbose "`n`n`n-----------------------------------------"
        write-verbose "Call to 'Execute-SQLQuery': PROCESS"
        write-verbose $query 
        write-verbose "-----------------------------------------`n`n`n"
        $command = $connection.CreateCommand()
        $command.CommandTimeout = $CommandTimeoutSeconds
        $command.CommandText = $query
        $result = $command.ExecuteReader()
        $table = new-object “System.Data.DataTable”
        $table.Load($result)
        Write-Output $table
    }
    end {
        write-verbose "Call to 'Execute-SQLQuery': END"
        $connection.Close()
    }
}

Execute-SQLQuery -DbInstance 'myServer\InstanceName' -DbCatalog 'myDatabase' -Query @"
select Mxmservsite.siteid as Marker_ID
 , mxmservsite.name as Name
 , 'SITE' as Group
 , '3' as Status
 , '' as Notes
 , mxmservsite.zipcode as Post_Code
 , 'GB' as Country
 , '' as Latitude
 , '' as Longitude
 , '' as Delete
 From mxmservsite --this wasn't in your original code
 Where dataareaid='ansa'
 "@ | Export-CSV '.\MyOutputFile.csv' -NoType 

可以在任何变化时触发某些事情;即你可以在桌面上创建一个触发器,然后用xp_cmdshell来执行一个脚本或类似的东西;但是这会导致性能问题(如果在没有完全理解的情况下使用,触发通常是一个糟糕的选择)。此外,xp_cmdshell可以为您带来一些安全风险。

还有很多其他方法可以实现这一目标;目前我有一个适用于PowerShell的东西,因为它为您提供了很大的灵活性和很少的开销。

另一个选择可能是使用linked servers来允许您的源数据库直接更新目标而无需CSV。

答案 1 :(得分:0)

另一个选项 - 创建一个运行bcp.exe命令的sql代理作业,以您想要的任何间隔(每小时)为您执行导出。使用bcp.exe,您可以指定文件位置,列/行终止符和过滤查询。

如果要在每次更改时导出,可以添加如上所述的after触发器,并简单地执行将异步执行的sql代理作业。如果您担心性能,那么您应该测试它以了解其影响。

如果您喜欢@ John的powershell脚本,请将其粘贴在sql代理作业中并安排它,如果有的话,可以将所有SQL任务集中在一起。

答案 2 :(得分:0)

您需要指定当前所在的服务器名称。您无法使用D $使用驱动器号,但需要使用共享驱动器名称。以下内容适用于2012年。

-- Declare report variables
DECLARE @REPORT_DIR VARCHAR(4000)
DECLARE @REPORT_FILE VARCHAR(100)
DECLARE @DATETIME_STAMP VARCHAR(14)
DECLARE @Statement VARCHAR(4000)
DECLARE @Command VARCHAR(4000)

--SET variables for the Report File
SET @DATETIME_STAMP = (SELECT CONVERT(VARCHAR(10), GETDATE(), 112) + REPLACE(CONVERT(VARCHAR(8), GETDATE(),108),':','')) -- Date Time Stamp with YYYYMMDDHHMMSS
SET @REPORT_DIR = '\\aServerName\SharedDirectory\' -- Setting where to send the report. The Server name and a Shared name, not a drive letter
SET @REPORT_FILE = @REPORT_DIR + 'Tables_' + @DATETIME_STAMP + '.csv' --the -t below is used for the csv file

--Create the CSV file report with all of the data. The @Statement variable must be used to use variables in the xp_cmdshell command.
SET @Statement = '"SELECT * FROM  sys.tables" queryout "'+@REPORT_FILE+'" -c -t"," -r"\n" -S"CurrentServerName\Databasename" -T' --The -S must be used with the -T
SET @Command = 'bcp '+@Statement+' '
EXEC master..xp_cmdshell @Command