从 PowerShell 将 NULL 插入数据库

Posted

技术标签:

【中文标题】从 PowerShell 将 NULL 插入数据库【英文标题】:Inserting NULL Into Database from PowerShell 【发布时间】:2018-09-20 14:51:19 【问题描述】:

我有通过 API 获取的数据,该 API 为我提供了一个 json 文件。我使用 PowerShell 将其转换为 PowerShell 对象。

$allusers = Get-Content 'test.txt' | Out-String | ConvertFrom-Json

我从这个对象中获取数据并将其插入到 SQL Server 数据库中。我遇到的问题是,对于对象中不存在的键,我想在数据库中插入一个 NULL。

我在这里探索了其他解决方案,大多数建议使用[DBNull]::Value

如果数组中特定用户的值不存在,我会设置变量:

$oa_email_id = [DBNull]::Value
$oa_email = [DBNull]::Value
$oa_sms_id = [DBNull]::Value
$oa_sms_phone = [DBNull]::Value

但是,对于空 INT 值,我插入了一个 0,对于空 VARCHAR(max) 值,插入了一个空白字符串。我有什么遗漏或做错了吗?

插入数据库:

$sql_insert_cmd = New-Object System.Data.SqlClient.SqlCommand
$sql_insert_cmd.CommandText = "
    INSERT INTO
        TEMP_OMNIALERT_CURRENT_SUBSCRIBERS
            (ID_NUM, OA_ID, OA_VALIDATED, OA_ACCOUNT_EXPIRATION_DATE, OA_OPTOUT_DATE, OA_EMAIL_ID,OA_EMAIL, OA_SMS_ID,OA_SMS_PHONE)
    VALUES
            ('"+    $id_num + "', '" +
                    $oa_id + "', '" +
                    $oa_validated + "', '" +
                    $oa_account_expiration_date + "', '" +
                    $oa_optout_date + "', '" +
                    $oa_email_id + "', '" +
                    $oa_email + "', '" +
                    $oa_sms_id + "', '" +
                    $oa_sms_phone + "')"

$sql_insert_cmd.Connection = $connection
$execute_insert = $sql_insert_cmd.ExecuteNonQuery()

表创建:

$sql_insert_cmd.CommandText = "
USE TmsEPly;
DROP TABLE IF EXISTS TEMP_OMNIALERT_CURRENT_SUBSCRIBERS;
CREATE TABLE
    TEMP_OMNIALERT_CURRENT_SUBSCRIBERS
    (
        SUBMISSION_ID int IDENTITY(1,1) NOT NULL PRIMARY KEY,
        ID_NUM VARCHAR(MAX) NOT NULL,
        OA_ID INT NOT NULL,
        OA_VALIDATED INT NOT NULL,
        OA_ACCOUNT_EXPIRATION_DATE VARCHAR(MAX) NOT NULL,
        OA_OPTOUT_DATE VARCHAR(MAX) NOT NULL,
        OA_EMAIL_ID INT NULL,
        OA_EMAIL VARCHAR(MAX) NULL,
        OA_SMS_ID INT NULL,
        OA_SMS_PHONE VARCHAR(MAX) NULL
    )"

【问题讨论】:

您尚未在插入的位置显示代码。我的猜测是问题出在您创建参数的位置。 我添加了插入语句 您是否尝试过删除这些字段周围的单引号? 所有插入都失败,没有单引号 您需要使用参数化语句以这种方式使用 null(使用 [DBNull]::Value)。如果要构建带有空值的单字符串插入语句,则必须使用不带任何引号的字符串“Null”作为值。不过,强烈建议使用参数。 【参考方案1】:

您是否会考虑加载数据表,然后将其写入数据库,而不是构建字符串?

使用您的表创建,我整理了以下测试,该测试成功地将数据加载到本地测试数据库上的 TEMP_OMNIALERT_CURRENT_SUBSCRIBERS 中。定义和构建数据表的代码很大,但只需要发生一次,然后可以在遍历 json 数据时根据需要将行添加到其中。需要注意的一点是,我在数据表中为 SUBMISSION_ID 创建了一个列并且从不填充它 - 这样它会跳过第一个标识列,而不是尝试插入它并失败。

###import the sqlserver module
ipmo sqlserver 

###your values
$oa_email_id = [DBNull]::Value
$oa_email = [DBNull]::Value
$oa_sms_id = [DBNull]::Value
$oa_sms_phone = [DBNull]::Value

###my temp values for the other columns
$ID_NUM = "a"
$OA_ID = 1 
$OA_VALIDATED = 1
$OA_ACCOUNT_EXPIRATION_DATE = get-date
$OA_OPTOUT_DATE = get-date

###define the datatable structure
$testTable = New-Object system.data.datatable "FileTable"
$col0 = New-Object system.Data.DataColumn SUBMISSION_ID,([int])
$col1 = New-Object system.Data.DataColumn ID_NUM,([string])
$col2 = New-Object system.Data.DataColumn OA_ID,([int])
$col3 = New-Object system.Data.DataColumn OA_VALIDATED,([int])
$col4 = New-Object system.Data.DataColumn OA_ACCOUNT_EXPIRATION_DATE,([string])
$col5 = New-Object system.Data.DataColumn OA_OPTOUT_DATE,([string])
$col6 = New-Object system.Data.DataColumn OA_EMAIL_ID,([int])
$col7 = New-Object system.Data.DataColumn OA_EMAIL,([string])
$col8 = New-Object system.Data.DataColumn OA_SMS_ID,([int])
$col9 = New-Object system.Data.DataColumn OA_SMS_PHONE,([string])

$testTable.columns.add($col0)
$testTable.columns.add($col1)
$testTable.columns.add($col2)
$testTable.columns.add($col3)
$testTable.columns.add($col4)
$testTable.columns.add($col5)
$testTable.columns.add($col6)
$testTable.columns.add($col7)
$testTable.columns.add($col8)
$testTable.columns.add($col9)

###add a new row and populate it
$row = $testTable.NewRow()
$row.ID_NUM = $ID_NUM
$row.OA_ID = $OA_ID
$row.OA_VALIDATED = $OA_VALIDATED
$row.OA_ACCOUNT_EXPIRATION_DATE = $OA_ACCOUNT_EXPIRATION_DATE
$row.OA_OPTOUT_DATE = $OA_OPTOUT_DATE
$row.OA_EMAIL_ID = $oa_email_id
$row.OA_EMAIL = $oa_email
$row.OA_SMS_ID = $oa_sms_id
$row.OA_SMS_PHONE = $oa_sms_phone
$testTable.Rows.Add($row)

###write the datatable to our target table
$testTable | write-sqltabledata -ServerInstance "localhost" -database "test" -schemaname "dbo" -tablename "TEMP_OMNIALERT_CURRENT_SUBSCRIBERS"

【讨论】:

【参考方案2】:

我想我做了上面 Mike Shepard 描述的事情,现在我的 NULL 值被插入了。

我改为将查询和插入语句改为参数:

$sql_insert_cmd.CommandText = "
    INSERT INTO
        TEMP_OMNIALERT_CURRENT_SUBSCRIBERS
            (ID_NUM, OA_ID, OA_VALIDATED, OA_ACCOUNT_EXPIRATION_DATE, OA_OPTOUT_DATE, OA_EMAIL_ID, OA_EMAIL, OA_SMS_ID, OA_SMS_PHONE) 
    VALUES
            (@id_num, @oa_id, @oa_validated, @oa_account_expiration_date, @oa_optout_date, @oa_email_id, @oa_email, @oa_sms_id, @oa_sms_phone)"


$sql_insert_cmd.Parameters.Add((New-Object DATA.SQLClient.SQLParameter("@id_num",[Data.SQLDBType]::VarChar, -1))) | OUT-NULL
$sql_insert_cmd.Parameters.Add((New-Object DATA.SQLClient.SQLParameter("@oa_id",[Data.SQLDBType]::Int))) | OUT-NULL
$sql_insert_cmd.Parameters.Add((New-Object DATA.SQLClient.SQLParameter("@oa_validated",[Data.SQLDBType]::Int))) | OUT-NULL
$sql_insert_cmd.Parameters.Add((New-Object DATA.SQLClient.SQLParameter("@oa_account_expiration_date",[Data.SQLDBType]::VarChar, -1))) | OUT-NULL
$sql_insert_cmd.Parameters.Add((New-Object DATA.SQLClient.SQLParameter("@oa_optout_date",[Data.SQLDBType]::VarChar, -1))) | OUT-NULL
$sql_insert_cmd.Parameters.Add((New-Object DATA.SQLClient.SQLParameter("@oa_email_id",[Data.SQLDBType]::Int))) | OUT-NULL
$sql_insert_cmd.Parameters.Add((New-Object DATA.SQLClient.SQLParameter("@oa_email",[Data.SQLDBType]::VarChar, -1))) | OUT-NULL
$sql_insert_cmd.Parameters.Add((New-Object DATA.SQLClient.SQLParameter("@oa_sms_id",[Data.SQLDBType]::Int))) | OUT-NULL
$sql_insert_cmd.Parameters.Add((New-Object DATA.SQLClient.SQLParameter("@oa_sms_phone",[Data.SQLDBType]::VarChar, -1))) | OUT-NULL

我使用插入数据:

$sql_insert_cmd.Parameters[0].Value = $user.username
$sql_insert_cmd.Parameters[1].Value = $user.id
$sql_insert_cmd.Parameters[2].Value = $user.validated
$sql_insert_cmd.Parameters[3].Value = $user.account_expiration_date
$sql_insert_cmd.Parameters[4].Value = $user.optout_date
$sql_insert_cmd.Parameters[5].Value = $oa_email_id
$sql_insert_cmd.Parameters[6].Value = $oa_email
$sql_insert_cmd.Parameters[7].Value = $oa_sms_id
$sql_insert_cmd.Parameters[8].Value = $oa_sms_phone

$sql_insert_cmd.ExecuteScalar()

【讨论】:

以上是关于从 PowerShell 将 NULL 插入数据库的主要内容,如果未能解决你的问题,请参考以下文章

Powershell将希伯来语文本插入图像

使用 Powershell 替换将字符插入 UNC 字符串

使用 Google Apps 脚本将 Null 值从表格插入 Mysql 数据库

在将数据从文件插入表时,如何用 NULL 替换 NA 值?

使用 Powershell 从 PostgreSQL 检索数据

如何使用powershell将数据插入XML childelement [duplicate]