【问题标题】:Show NULL values in result table when SQL query is executed执行 SQL 查询时在结果表中显示 NULL 值
【发布时间】:2017-12-08 20:50:30
【问题描述】:

我有一个执行 SQL 文件并在控制台中打印结果的脚本(目前)。问题是我需要区分 NULL 值和 Result 表中返回的空字符串。

这是查询在 Management Studio 中返回的内容:

可以看到它包含字符串、空字符串和NULL值。

这是查询在 PowerShell IDE 中返回的内容:

NULL 和空没有区别。

最后几列也被剪掉,只打印前 10 列。

我该如何解决这个问题?

这是我的代码:

$ConnectionString = "Data Source=...;Initial Catalog=...;User Id=..;Password=.."
$FolderToSQLFiles = "C:\SQLFilesTestFolder";

#function that executes sql queries and return result tables
function GetSQLresults {
    Param(
        [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$True, Position=0)] $SQLqueryText, # sql query text returned from file
    )

    $objConnection = New-Object System.Data.SqlClient.SqlConnection;
    $objConnection.ConnectionString = $ConnectionString

    $objConnection.Open();

    $ObjCmd = New-Object System.Data.SqlClient.SqlCommand;
    $ObjCmd.CommandText = $SQLqueryText;
    $ObjCmd.Connection = $objConnection;
    $ObjCmd.CommandTimeout = 0;

    $objAdapter = New-Object System.Data.SqlClient.SqlDataAdapter;
    $objAdapter.SelectCommand = $ObjCmd;
    $objDataSet = New-Object System.Data.DataSet;

    $objAdapter.Fill($objDataSet);

    $ResultSets = @(); #adding all result tables to array

    for ($i=0; $i -lt $objDataSet.Tables.Count; $i++) {
        $tmpResultTable = $objDataSet.Tables[$i] | Format-Table | Out-String;
        $ResultSets += $tmpResultTable;
    }

    return $ResultSets 

    $query = $null;

    $objDataSet = $null;

    $objConnection.Close();
    $objConnection = $null;
}

Get-ChildItem $FolderToSQLFiles -Filter *.sql | Foreach-Object {
    $tmpSQLfilePath = $_.FullName #getting the sql file full path
    $tmpSQLfileContent = (Get-Content $tmpSQLfilePath) -join "`n"  #getting the content of the sql

    GetSQLresults -SQLqueryText $tmpSQLfileContent  #passing the sql query to the executing funciton
}

【问题讨论】:

    标签: sql-server powershell null


    【解决方案1】:

    PowerShell 自动将空值转换为空字符串以进行输出。您需要检查字段中值的类型并相应地调整输出/值。

    这样的事情应该可以工作:

    GetSQLresults ... |
        Select-Object -Property *,@{n='Col006',e={
            if ($_.Col006 -is [DBNull]) {'NULL'} else {$_.Col006}
        }} -Exclude Col006
    

    【讨论】:

    • 问题是我也不知道每个表的列名。我执行了许多查询,它们都有不同的结果表。此外,一个查询可以有多个结果表。 : /
    • 然后你需要枚举表,枚举列,并为列中的每个值替换[DBNull]类型的值。我不会为此提供交钥匙解决方案。
    【解决方案2】:

    在 Powershell 中使用:$SQL_Command = "sqlcmd -S $DbServer -U $SQL_User -P $SQL_Pass -i $TSQL_File -o$CSV_OutPut_FileName -s ',' -w 65530"

    调用表达式 $SQL_Command

    第一个变量 ($SQL_Command) 存储 sqlcmd 命令 Invoke-Expression cmdlet 计算或运行指定字符串作为命令

    $TSQL_File 变量是包含 sql 语句的文件名(例如:SELECT GUID FROM TableName....sql server 中的唯一标识符数据类型,或者您可以使用 SELECT * FROM TableName)

    SQL Server 中的输出将如您所愿(NULL 和空字符串)...希望得到帮助。

    【讨论】:

      【解决方案3】:
      #----------------------------------------------------------------------------------------------------------   
      #--- This will generate the result that you want 
      #----------------------------------------------------------------------------------------------------------   
      #--- Each line of TSQL_FileName.TXT ($ScriptsArray) contains a file name ($TSQL_File) of the TSQL statement that need to be execute
      #----------------------------------------------------------------------------------------------------------   
      FOREACH ($TSQL_File in $ScriptsArray)
      { $Num_TSQL_File++
        $Result_MSG = ''
        #----------------------------------------------------------------------------------------------------------   
        #--- GENERATE OUT PUT FILE NAME USE FOR CSV FILE WHEN WE RUN sqlcmd 
        #----------------------------------------------------------------------------------------------------------   
        $OutPut_File = (Get-Item $TSQL_File).Basename+'_'+$OutPut_DateTime
        $OutPut_File = $OutPut_File.replace(' ','_')
        $OutPut_File = $OutPut_File.replace('.','_')
        $OutPut_File = $OutPut_File+'.CSV'
        $OutPut_Error = ''
        $SQL_Command = "sqlcmd -S $DbServer -U $SQL_User -P $SQL_Pass -i $TSQL_File -o $OutPut_File -s ',' -w 65530"
        Invoke-Expression $SQL_Command 
        $OutPut_Array = Get-Content $OutPut_File
        $ThirdLine = "|"+$OutPut_Array[3]+"|"
        #----------------------------------------------------------------------------------------------------------
        #--- Determine if an error had occured, if so send email notification
        #----------------------------------------------------------------------------------------------------------
        IF (($OutPut_Array -like "Error*") -or ($OutPut_Array -like "Msg*") -or ($OutPut_Array -like "Invalid*")  -or ($OutPut_Array -like "Sqlcmd: Error*") )
        { $OutPut_Error = (Get-Item $TSQL_File).Basename+'_'+$OutPut_DateTime+'.ERR'
          $OutPut_Array | out-file ".\$OutPut_Error"
          $Result_MSG = 'Error!'
          $OutPut_File = $OutPut_Error
          $OutPut_FileSizeKb = $NumOfRow_Send = 0
          $global:DbErr++
          "{0,-16} {1,-40} {2,-60} {3,-10} {4,-4} {5,-4}" -f $DbServer, $TSQL_File, $OutPut_File, [int]$OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG
          $Results_Array += ,@($Results_Array_Index, $DbServer, $TSQL_File, $OutPut_File, $OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG)  
          $Results_Array_Index++
        }
        ELSE
        { #----------------------------------------------------------------------------------------------------------
          #--- Determine if zero row return from query, if so modify the array so that it will send only header info
          #----------------------------------------------------------------------------------------------------------
          IF ( ($OutPut_Array.Length -EQ 3) -and ($ThirdLine -EQ '||') )
          { $NeedFix_Array = Get-Content $OutPut_File
            #-------------------------------------------------------------
            #--- MODIFY THE ARRAY SO THAT IT WILL SEND ONLY THE HEADER
            #-------------------------------------------------------------
            $NeedFix_Array = $NeedFix_Array[1]
            #-----------------------------------------------------------
            #--- REMOVE BLANK SPACE FROM THE LINE
            #-----------------------------------------------------------
            $NeedFix_Array = $NeedFix_Array -replace '\s+', ' '
            $NeedFix_Array = $NeedFix_Array -replace ' ,', ','
            $NeedFix_Array = $NeedFix_Array -replace ', ', ','
            #-----------------------------------------------------------
            $NeedFix_Array | out-file $OutPut_File -Encoding ASCII
            $OutPut_FileSizeKb = (Get-Item $OutPut_File).length/1KB
            $OutPut_FileSizeKb = [int][Math]::Ceiling($OutPut_FileSizeKb)
            $NumOfRow_Send = 1
            $Num_CSV_File_Created++
            "{0,-16} {1,-40} {2,-60} {3,-10} {4,-4} {5,-4}" -f $DbServer, $TSQL_File, $OutPut_File, [int]$OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG
            $Results_Array += ,@($Results_Array_Index, $DbServer, $TSQL_File, $OutPut_File, $OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG)  
            $Results_Array_Index++
          }
          #----------------------------------------------------------------------------------------------------------
          #--- REMOVE 1st LINE AND '-----' IN 3rd LINE AND FIX THE SPACES BETWEEN COMMA
          #----------------------------------------------------------------------------------------------------------
          ELSE
          { $NeedFix_Array = Get-Content $OutPut_File
            #-------------------------------------------------------------
            #--- REMOVE THE FIRST LINE 
            #-------------------------------------------------------------
            $NeedFix_Array = $NeedFix_Array[1..($NeedFix_Array.Length-1)]
            #-------------------------------------------------------------
            #--- REMOVE THE SECOND LINE AFTER THE FIRST LINE WERE REMOVE
            #-------------------------------------------------------------
            $NeedFix_Array = $NeedFix_Array[0,0+2..($NeedFix_Array.length - 1)]
            $NeedFix_Array = $NeedFix_Array[1..($NeedFix_Array.Length-1)]
            #-----------------------------------------------------------
            #--- REMOVE BLANK SPACE FROM THE LINE
            #-----------------------------------------------------------
            $NeedFix_Array = $NeedFix_Array -replace '\s+', ' '
            $NeedFix_Array = $NeedFix_Array -replace ' ,', ','
            $NeedFix_Array = $NeedFix_Array -replace ', ', ','
            #-----------------------------------------------------------
            $NeedFix_Array | out-file $OutPut_File -Encoding ASCII
            $OutPut_FileSizeKb = (Get-Item $OutPut_File).length/1KB
            $OutPut_FileSizeKb = [int][Math]::Ceiling($OutPut_FileSizeKb)
            $NumOfRow_Send = $NeedFix_Array.Length
            $Num_CSV_File_Created++
            "{0,-16} {1,-40} {2,-60} {3,-10} {4,-4} {5,-4}" -f $DbServer, $TSQL_File, $OutPut_File, [int]$OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG
            $Results_Array += ,@($Results_Array_Index, $DbServer, $TSQL_File, $OutPut_File, $OutPut_FileSizeKb, $NumOfRow_Send, $Result_MSG)  
            $Results_Array_Index++
          }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-15
        • 2013-12-16
        • 1970-01-01
        • 1970-01-01
        • 2018-01-19
        相关资源
        最近更新 更多