2017-03-17 55 views
1

我需要运行一系列查询和结果导出到一个平面文件,但这个文件是一种特殊的:CSV文件

  1. 列分隔符必须是一个|
  2. 我需要放置“围绕字符或varchar列BU如果任何字符或varchar列为NULL为特定的行,我不能放置”。如果该值是一个空字符串,那么是的,我需要放置它们。

我发现了一个解决方法,在T-SQL中构建整个记录,但是我需要为每个新构建的查询都做这个工作。

任何想法

+0

一个选项是使用BCP:[如何使用BCP提取管道分隔数据](http://dba.stackexchange.com/q/111378/43889) – SqlZim

回答

1

有不同的选择在这里:

  • 您可以使用BCP工具来提取数据
  • 您可以使用集成服务,如果你有可能做到这一点,每天一次并在SQL代理中安排包。
  • 您可以在管理Studio中使用导出向导,然后选择您需要的分隔符:

右键单击数据库,然后单击导出数据。 一直走在数据源,并在数据的目的地把你的文件,分隔的格式和(“)作为文本限定符:

enter image description here

然后选择要解压缩的数据表(或查询)并指定“垂直栏”作为列分隔符 enter image description here

下一步是运行任务(这里还提供了选项来保存SSIS包以再次运行它只要你想)

希望这可以帮助你。

1

可以使用SQLPS模块,然后选择您的表

Import-Module Sqlps -DisableNameChecking; 
Invoke-Sqlcmd -ServerInstance "yourservername" -Database "yourdatabasename" -Query "select top 2 zonetable1, zonetable2 from dbo.yourtable" | 
    Export-Csv "c:\temp\result.csv" -NoTypeInformation 
0

下面是一个使用PowerShell的一个解决方案,因为你的标签,在你的问题。

  • 使用.Net库执行SQL(即与Invoke-SqlCmd相反)。这样可以避免路径更改(导入的SQLPS模块的副作用),并且意味着您可以通过在数据中查找DbNull来查找空值。
  • 删除那些不是请求数据的属性,而是删除DataRow对象的属性。
  • 对于我们结果中的每个属性,检查它是否是DBNull。如果是,请用标记字符串替换它(该字符串包含一个GUID,因此很可能偶然出现在源数据中)。
  • 使用管道分隔符将数据转换为CSV
  • 用空白(即不带引号)替换用引号括起来的所有出现的标记。
  • 结果写入文件

clear-host 
function Invoke-SQLQuery { 
    [CmdletBinding()] 
    param (
     [Parameter(Mandatory = $true)] 
     [string]$ServerInstance 
     , 
     [Parameter(Mandatory = $true)] 
     [string]$Database 
     , 
     [Parameter(Mandatory = $true)] 
     [string]$Query 
     , 
     [Parameter(Mandatory = $false)] 
     [int]$CommandTimeoutSeconds = 30 #30 is the SQL default 
    ) 
    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 { 
     $command = $connection.CreateCommand() 
     $command.CommandTimeout = $CommandTimeoutSeconds 
     $command.CommandText = $query 
     $result = $command.ExecuteReader() 
     $table = new-object "System.Data.DataTable" 
     $table.Load($result) 
     $table | Convert-DataRowToPSCustomObject 
    } 
    end { 
      $connection.Close() 
    } 
} 
function Convert-DataRowToPSCustomObject { 
    [CmdletBinding()] 
    param (
     [Parameter(ValueFromPipeline = $true)] 
     [System.Data.DataRow]$Row 
    ) 
    process { 
     [PSObject]($Row | Select * -ExcludeProperty RowError, RowState, Table, ItemArray, HasErrors) 
    } 
} 
#this gives us a nice way to distinguish nulls from blanks in csv rows 
function Convert-DbNullToMarker { 
    [CmdletBinding()] 
    param(
     [Parameter(Mandatory = $true, ValueFromPipeline = $true)] 
     [PSObject]$Data 
    ) 
    process { 
     $Data | Get-Member -MemberType NoteProperty | % Name | %{ 
      if($Data.$_ -is [DbNull]) { 
       $Data.$_ = 'DbNullMarker{fdb653bf-0810-4893-a076-e3d935d9e6ba}' 
      } 
     } 
     $Data 
    } 
} 

#this gives us a nice way to distinguish nulls from blanks in csv rows 
function Convert-DbNullMarkerToNull { 
    [CmdletBinding()] 
    param(
     [Parameter(Mandatory = $true, ValueFromPipeline = $true)] 
     [string]$CsvRow 
    ) 
    process { 
     $CsvRow -replace '"DbNullMarker{fdb653bf-0810-4893-a076-e3d935d9e6ba}"','' 
    } 
} 


Invoke-SqlQuery -ServerInstance "." -Database "master" -Query "select * from (values (null, 'hello'), ('hi', 'world')) x(a, b)" | 
    Convert-DbNullToMarker -Verbose | 
    ConvertTo-Csv -Delimiter '|' -NoTypeInformation | 
    Convert-DbNullMarkerToNull | 
    Out-File -FilePath (Join-Path $PSScriptRoot 'SqlCsvDemo.csv') -Encoding utf8 -Force