希望我不要因为问一个简单的问题而烦恼任何人!
我需要将数据从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>
干杯
答案 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