Loading

powershell脚本将json文件至SQL Server

一、问题引入

之前写过一篇博客关于 T-SQL 脚本将 json 文件至 SQL Server,但 T-SQL 脚本只能在 SSMS 软件下运行。

现在迫切需要一种能在操作系统 shell 中运行的脚本,在 StackOverflow 中查询到 powershell 可以将 json 文件导入 SQL Server。

二、解决过程

💡 需求是递归指定目录下的所有 json 格式文件,解析 json 内容并插入指定数据库的表

1️⃣ 案例测试条件

准备了一个目录,其中目录下存在子目录,在子目录下新建文件( json 格式,ansi 编码),一共准备了四个文件,其中一个文件内容如下:

{
    "FixtureID": 2,
    "EventDate":"2023-02-27 01:09:58",
    "Venue":"vanue2023-02-27",
    "CityName":"杭州",
    "EventID":0
}

2️⃣ 数据库新建表

create table TestTable
(
    FixtureID int,
    EventDate datetime2(0),
    Venue     varchar(50),
    CityName  nvarchar(20),
    EventID   tinyint
)

3️⃣ 新建并修改powershell脚本

# SQL导入文件夹json. 将xxx替换为实际参数

$connectionString = "Server=xxx.xxx.xxx.xxx;Database=xxx;Integrated Security=false;User ID=xxx;Password =xxx;"

Function Insert_YourTable($json) {
    $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
    $insertQuery = @"
INSERT INTO dbo.xxx(
     FixtureID
    ,EventDate
    ,Venue
    ,CityName
    ,EventID
)
VALUES(
     @FixtureID
    ,@EventDate
    ,@Venue
    ,@CityName
    ,@EventID
);
"@
    $insertCommand = New-Object System.Data.SqlClient.SqlCommand($insertQuery, $connection)
    [void]($insertCommand.Parameters.Add("@FixtureID", [System.Data.SqlDbType]::Int).Value = if($null -eq $json.FixtureID) {[DbNull]::Value} else {$json.FixtureID} )
    [void]($insertCommand.Parameters.Add("@EventDate", [System.Data.SqlDbType]::DateTime2).Value = if($null -eq $json.EventDate) {[DbNull]::Value} else {$json.EventDate} )
    [void]($insertCommand.Parameters.Add("@Venue", [System.Data.SqlDbType]::VarChar, 50).Value = if($null -eq $json.Venue) {[DbNull]::Value} else {$json.Venue} )
    [void]($insertCommand.Parameters.Add("@CityName", [System.Data.SqlDbType]::NVarChar, 20).Value = if($null -eq $json.CityName) {[DbNull]::Value} else {$json.CityName} )
    [void]($insertCommand.Parameters.Add("@EventID", [System.Data.SqlDbType]::TinyInt).Value = if($null -eq $json.EventID) {[DbNull]::Value} else {$json.EventID} )   
    $connection.Open()
    try {
        [void]$insertCommand.ExecuteNonQuery()
    }
    catch [System.Data.SqlClient.SqlException] {
        Write-Host "Error inserting record. Violate PRIMARY KEY rule || $json" -ForegroundColor Yellow
    }
    finally {
        $Error.Clear()
    }
    $connection.Close()
}

# ############
# ### MAIN ###
# ############

try {
    $jsonFiles = Get-ChildItem "D:\temp\time\*.info" -Recurse
    foreach ($jsonFile in $jsonFiles) {
        Write-Host "Importing $($jsonFile.FullName)..."
        try {
            #$json = [System.IO.File]::ReadAllText($jsonFile.FullName) | ConvertFrom-Json
            $json = Get-Content $jsonFile.FullName -Encoding oem | ConvertFrom-Json
        }
        catch [System.ArgumentException]{
            Write-Host "Error parsing json. File ignored" -ForegroundColor Yellow
        }
        Insert_YourTable -json $json
    }
}
catch {
    throw    
}

💡 重点语句解释

$connectionString = "Server=xxx.xxx.xxx.xxx;Database=xxx;Integrated Security=false;User ID=xxx;Password =xxx;"
通过powershell连接数据库,需要指定数据库服务器的ip,数据库名称,用户名和密码

$json = Get-Content $jsonFile.FullName -Encoding oem | ConvertFrom-Json
json 格式文件编码是 ansi,读取时不能采用默认编码(utf8)。json 字符串转换 json 字典只能是 utf8 编码。
此处读取文件编码格式采用 MS-DOS 系统默认编码(oem: Uses the default encoding for MS-DOS and console programs)

4️⃣ 数据库验证

三、反思总结

powershell 功能很强大,作为windows系统内置 shell 无疑是性能最好的。

大胆假设,小心求证。

四、参考引用

Import an entire directory of json files with SQL Server 2016

posted @ 2023-03-03 13:50  eiSouthBoy  阅读(128)  评论(0)    收藏  举报