1

I have long INSERT queries that insert values to table with over 50 columns. Is there any tool to parse this long query to key-value representation?

like:

INSERT INTO sometable(col1, col2, col3) VALUES (1,2,3)

parse to:

col1: 1
col2: 2
col3: 3

So it would be easier to analyze.

1
  • Python should do it in a snap
    – mustaccio
    Mar 15, 2019 at 13:36

3 Answers 3

2

One method is with the Microsoft.SqlServer.TransactSql.ScriptDom. This can be used from a .NET application or PowerShell script. The assembly is available as a NuGet package or, if you already have SQL Server tools installed, you can reference an existing assembly in the Program Files (x86) folder.

Below is a PowerShell example that uses the assembly installed by SSMS.

Add-Type -Path "C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio\Extensions\Application\Microsoft.SqlServer.TransactSql.ScriptDom.dll"

$query = "INSERT INTO sometable(col1, col2, col3) VALUES (1,2,3)"

# use the appropriate TSqlParser version for the scripts being parsed
$parser = New-Object Microsoft.SqlServer.TransactSql.ScriptDom.TSql140Parser($true)
$parseErrors = New-Object System.Collections.Generic.List[Microsoft.SqlServer.TransactSql.ScriptDom.ParseError]

$scriptReader = New-Object System.IO.StringReader($query)

$fragment = $parser.Parse($scriptReader, [ref]$parseErrors)
if($parseErrors.Count -eq 0) {
    for($i = 0; $i -lt $fragment.Batches[0].Statements[0].InsertSpecification.Columns.Count; ++$i) {
        $columnName = $fragment.Batches[0].Statements[0].InsertSpecification.Columns[$i].MultiPartIdentifier[0].Value 
        $columnValue = $fragment.Batches[0].Statements[0].InsertSpecification.InsertSource.RowValues[0].ColumnValues[$i].Value
        Write-Host "$columnName`: $columnValue"
    }
}
else {
    Write-Host "$($parseErrors.Count) parsing errors. First error: $($parseErrors[0].Message)" -ForegroundColor Red
}
4
  • A good solution but doesn't work with more complex value types like function calls and conversions and variable references.
    – Konrad
    Mar 15, 2019 at 14:27
  • I converted it to C# and modified a little bit by using Sql150ScriptGenerator. Thanks
    – Konrad
    Mar 15, 2019 at 14:33
  • requires more work but works pastebin.com/0RN9PssE
    – Konrad
    Mar 15, 2019 at 14:40
  • 1
    @Konrad, the code I provided was just an example for this particular use case but can be extended for other specialized needs.
    – Dan Guzman
    Mar 15, 2019 at 14:47
1

This may or may not sufficiently address your problem, but when I'm faced with this situation, I paste the statement into Poor SQL and view the formatted results

Original:

INSERT INTO sometable(col1, col2, col3) VALUES (1,2,3)

Formatted:

INSERT INTO sometable (
    col1
    ,col2
    ,col3
    )
VALUES (
    1
    ,2
    ,3
    )

I then bring up Word and create a 2 column table. I paste the columns from the formatted result into the first column of the Word table and paste the values from the formatted result into the second column of the Word table

enter image description here

1
  • Great simple method.
    – Konrad
    Mar 15, 2019 at 14:34
0

I don't use any tool, but I structure the insert with each column on a row and I use SELECT instead of VALUES. I give an alias for each value which gives me a clue about what column is used in insert. Example:

INSERT INTO sometable
(
   col1,
   col2,
   col3
)
SELECT
   col1 = 1,
   col2 = 2,
   col3 = 3

Pay attention that the alias in the select is just an alias ie if you write

SELECT
   col2 = 2,
   col1 = 1,
   col3 = 3

the value from col2 (2) will still go in the first field in the insert (col1).

Not the answer you're looking for? Browse other questions tagged or ask your own question.