【问题标题】:Failed to Insert JSON data in SQLSERVER If column name contains APOSTROPHE('s)如果列名包含 APOSTROPHE('s),则无法在 SQLSERVER 中插入 JSON 数据
【发布时间】:2020-05-17 02:00:20
【问题描述】:

我正在尝试通过使用 PowerShell 调用存储过程将数据 Json 格式数据加载到 SQL Server 中

以下是 JSON 数据

{
    "id":"2aa7ce44-2ac1-4efb-a5df-6c34086744b7",
    "isReadOnly":false,
    "isOnDedicatedCapacity":false,
    "capacityMigrationStatus":"",
    "type":"Group",
    "state":"Active",
    "name":"Wes' Test Team",
    "dashboards":[],
    "reports":[],
    "datasets":[],
    "users":[]
},
{
    "id":"cb876bcc-285a-40d7-a120-f23e73baafe8",
    "isReadOnly":false,
    "isOnDedicatedCapacity":false,
    "capacityMigrationStatus":"",
    "type":"Group",
    "state":"Active",
    "name":"Kehat's Corner",
    "dashboards":[],
    "reports":[],
    "datasets":[],
    "users":[]
}

无法插入数据,因为列名包含 '(APOSTROPHE) 并且脚本无法加载数据。

如果列名在数据中有 APOSTROPHE,有人可以帮助我如何克服。

PowerShell 脚本

Connect-PowerBIServiceAccount 
$PBIGroupsFile = "C:\TEMP\PBIGroupsExpanded.json"
$ActiveGroupsURLExPersonal = '/admin/groups?$top=5000&' + '$filter=type ne' + " 'PersonalGroup'" + '&$expand=dashboards,reports,datasets,users'
Invoke-PowerBIRestMethod -Url $ActiveGroupsURLExPersonal -Method Get | Out-File $PBIGroupsFile

存储过程

ALTER PROCEDURE [dbo].[InsertInventoryDataFromAPI_Temp]
    @JSON NVARCHAR(MAX) 
AS
BEGIN

DECLARE @PARSSEDJSON NVARCHAR(MAX)= SUBSTRING(@JSON,CHARINDEX('"value":',@JSON)+8,LEN(@JSON)-CHARINDEX('"value":[',@JSON)-10)

select  ROW_NUMBER () OVER (ORDER BY id) AS RowNum,* INTO #FLJSON
FROM OPENJSON(REPLACE(REPLACE(@PARSSEDJSON, CHAR(13)+CHAR(10), ''),'''',''))
WITH(
    id nvarchar(max) '$.id',
    isReadOnly nvarchar(max) '$.isReadOnly',
    isOnDedicatedCapacity nvarchar(max) '$.isOnDedicatedCapacity',
    capacityId nvarchar(max) '$.capacityId',
    capacityMigrationStatus nvarchar(max) '$.capacityMigrationStatus',
    type nvarchar(max) '$.type',
    state nvarchar(max) '$.state',
    name nvarchar(max) '$.name',
    dashboards nvarchar(max) '$.dashboards' AS JSON,
    reports nvarchar(max) '$.reports' AS JSON,
    datasets nvarchar(max) '$.datasets' AS JSON,
    users nvarchar(max) '$.users' AS JSON
    ) 

--Load Workspace Info
    INSERT INTO dbo.Workspace_temp
    Select id, isReadOnly,isOnDedicatedCapacity,capacityId,capacityMigrationStatus,type,state,name from #FLJSON

使用 PowerShell 调用存储过程

$JSON = Get-Content "C:\TEMP\PBIGroupsExpanded.json"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server=$SQLServer;Database=$SQLDBName;Integrated Security=True;"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = "EXEC [dbo].[InsertInventoryDataFromAPI_Temp] '$JSON'"
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$SqlConnection.Open()
$SQLReturn=$SQLCmd.ExecuteNonQuery()
$SqlConnection.Close()

【问题讨论】:

  • 在 PowerShell 脚本中使用参数化查询。这将避免引用问题和other issues,如果您需要帮助,请将相关的 PowerShell 代码 sn-p 添加到您的问题中。
  • @danGuzman 添加了 PowerShell 脚本你能帮我吗??
  • @Beerendrasaragadam 请提供调用存储过程的powershell代码
  • @Beerendrasaragadam,您添加的 sn-p 检索 json 数据,我认为这是有效的。添加像 Misery 要求的那样调用 proc 的 sn-p。

标签: json sql-server powershell


【解决方案1】:

正如@DanGuzman 在 cmets 中指出的,你需要使用 SQL 参数来避免这个问题

$SqlCmd.CommandText = "EXEC [dbo].[InsertInventoryDataFromAPI_Temp] @JSON"
$SqlCmd.Parameters.AddWithValue("@JSON", $JSON)

【讨论】:

    【解决方案2】:

    下面是一个参数化查询示例。我没有在此处包含 SqlDataAdapter,因为 proc 调用不需要它。

    $SqlCmd = New-Object System.Data.SqlClient.SqlCommand("[dbo].[InsertInventoryDataFromAPI_Temp]", $SqlConnection)
    $SqlCmd.CommandType = [System.Data.CommandType]::StoredProcedure
    $jsonParameter = $SqlCmd.Parameters.Add("@JSON", [System.Data.SqlDbType]::NVarChar, -1)
    $jsonParameter.Value = $JSON
    $SqlConnection.Open()
    $SQLReturn=$SQLCmd.ExecuteNonQuery()
    $SqlConnection.Close()
    

    【讨论】:

    • 我尝试了上面的方法并得到错误说字符串无法转换为对象。
    • 使用“0”参数调用“ExecuteNonQuery”时出现异常:“无法将参数值从 Object[] 转换为字符串。”在 line:15 char:1 + $SQLReturn=$SQLCmd.ExecuteNonQuery() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : InvalidCastException
    • @Beerendrasaragadam, Get-Content 默认返回一个对象数组。添加 -Raw 开关以将整个文件内容作为字符串返回:Get-Content -Raw。另外,我不确定您为什么在 proc 中使用SUBSTRING,但该代码会破坏 JSON。我认为您可以将其删除并直接在OPENJSON中使用@JSON参数。
    猜你喜欢
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 2012-08-19
    • 2014-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    • 2020-07-31
    相关资源
    最近更新 更多