数据源中String类型的给定值无法转换为指定目标列

时间:2018-05-18 09:39:10

标签: sql-server string powershell datatable uniqueidentifier

我在这里尝试的是,使用PowerShell Script将.xml文件中的数据加载到SQL Server数据库。

我的脚本如下:

$dataSource = 'dtsrc';                                       
$database = 'tempdb';   #DB

$connection = New-Object System.Data.SqlClient.SqlConnection;  #setting connection
$connection.ConnectionString = "Server=$dataSource;Database=$database;Integrated Security=True;";
$connection.Open();

$command = New-Object System.Data.SqlClient.SqlCommand;
$command.Connection = $connection;

$as = New-Object System.Data.SqlClient.SqlDataAdapter;
$as.SelectCommand = $command;
$filename = 'C:\DCT\XML\apc.xml';            #file to be loaded into sql server database table

$ds = New-Object System.Data.DataSet;
$ds.ReadXml($filename);    #reading from the file -- line gives output InferSchema

$dt = New-Object System.Data.DataTable;

$dt.Columns.Add("StartTime",[datetime]);
$dt.Columns.Add("EndTime",[datetime]);
$dt.Columns.Add("Status",[int]);
$dt.Columns.Add("ProcessedTime",[datetime]);
$dt.Columns.Add("ScheduleId",[guid]);
$dt.Columns.Add("Model",[string]);
$dt.Columns.Add("ModelVersion",[string]);
$dt.Columns.Add("ModelVersionState",[string]);
$dt.Columns.Add("ModifiedTime",[datetime]);
 $dt.Columns.Add("WriteBackLastRunTime",[datetime]);
 $dt.Columns.Add("ModifiedBy",[string]);
 $dt.Columns.Add("ModelType",[int]);
 $dt.Columns.Add("IsTimeRange",[int]);#b
 $dt.Columns.Add("WriteBackStatus",[int]);
 $dt.Columns.Add("RetryWriteBack",[int]);#b
 $dt.Columns.Add("NumOfRetry",[int]);
 $dt.Columns.Add("FrequencyUnits",[int]);
 $dt.Columns.Add("ScheduleType",[int]);
 $dt.Columns.Add("CustomType",[int]);
 $dt.Columns.Add("ShiftStartTime",[datetime]);
 $dt.Columns.Add("StartWeekDay",[int]);
 $dt.Columns.Add("EndWeekDay",[int]);
 $dt.Columns.Add("WritebackProcessedTime",[datetime]);
 $dt.Columns.Add("DiagStatus",[int]);
 $dt.Columns.Add("AccountingPeriodCase_PK_ID",[guid]);

 $dt = $ds.Tables[0];

$bcp = New-Object 'Data.SqlClient.SqlBulkCopy' $connection; #bulkcopy to the destination table.
$bcp.DestinationTableName = 'dbo.tempor';

#$bcp.ColumnMappings.Count;
$bcp.ColumnMappings.Clear();

$bcp.ColumnMappings.Add('StartTime','StartTime');
$bcp.ColumnMappings.Add('EndTime','EndTime');
$bcp.ColumnMappings.Add('Status','Status');
$bcp.ColumnMappings.Add('ProcessedTime','ProcessedTime');
$bcp.ColumnMappings.Add('ScheduleId','ScheduleId');
$bcp.ColumnMappings.Add('Model','Model');
$bcp.ColumnMappings.Add('ModelVersion','ModelVersion');
$bcp.ColumnMappings.Add('ModelVersionState','ModelVersionState');
$bcp.ColumnMappings.Add('ModifiedTime','ModifiedTime');
$bcp.ColumnMappings.Add('WriteBackLastRunTime','WriteBackLastRunTime');
$bcp.ColumnMappings.Add('ModifiedBy','ModifiedBy');
$bcp.ColumnMappings.Add('ModelType','ModelType');
$bcp.ColumnMappings.Add('IsTimeRange','IsTimeRange');
$bcp.ColumnMappings.Add('WriteBackStatus','WriteBackStatus');
$bcp.ColumnMappings.Add('RetryWriteBack','RetryWriteBack');
$bcp.ColumnMappings.Add('NumOfRetry','NumOfRetry');
$bcp.ColumnMappings.Add('FrequencyUnits','FrequencyUnits');
$bcp.ColumnMappings.Add('ScheduleType','ScheduleType');
#$bcp.ColumnMappings.Add('CustomType','CustomType');
#$bcp.ColumnMappings.Add('ShiftStartTime','ShiftStartTime');
#$bcp.ColumnMappings.Add('StartWeekDay','StartWeekDay');
#$bcp.ColumnMappings.Add('EndWeekDay','EndWeekDay');
$bcp.ColumnMappings.Add('WritebackProcessedTime','WritebackProcessedTime');
$bcp.ColumnMappings.Add('DiagStatus','DiagStatus');
$bcp.ColumnMappings.Add('AccountingPeriodCase_PK_ID','AccountingPeriodCase_PK_ID');    

if ($connection.State -ne [Data.ConnectionState]::Open) {

    'Connection to DB is not open.'

    Exit

}

$bcp.WriteToServer($dt);        #writing to server 
$connection.Close();

我面临的错误是:

Exception calling "WriteToServer" with "1" argument(s): "The given value of type String from the data source cannot be converted to type uniqueidentifier of the specified target column." At C:\Documents\DCT\SavedScripts\XMLtoDB\AccountingPeriodCases\sample.ps1:91 char:1
+ $bcp.WriteToServer($dt);        #writing to server
+ ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : InvalidOperationException

并且我创建的表具有数据类型的列:

enter image description here

问题是,我想我需要转换在ScheduleId和AccountingPeriodCase_PK_ID列下的数据表中的String,因为它们没有转换为uniqueidentifier。

我尝试过使用 [System.Guid]::Parse($dt.Columns[4]); [System.Guid]::Parse($dt.Columns[24]);

但错误重复。

要在thr ScheduleId和AccountingPeriodCase_PK_ID下加载的xml内容如下所示:

<ScheduleId>db6f3178-4702-456c-904b-2cd833b54efa</ScheduleId>
<AccountingPeriodCase_PK_ID>9544940d-8d1a-e711-80d3-0050569c2fb6</AccountingPeriodCase_PK_ID>

有人可以帮我解决这个问题吗? 谢谢

1 个答案:

答案 0 :(得分:0)

从我之前遇到过的scenario,它归结为你输入的来源。

问题是,如果您正在阅读XML文件,那么您一定会收到错误,因为在阅读flat-file(txt, csv)XML时,{{1}将未定义的类型解析为String。诀窍是对源进行某种控制。如果您的来源是PowerShell变量,例如PowerShelldatatable,那么您可以直接将此变量中的值插入到目标表中,因为列中的列的原始数据类型是表保存。

这是我遵循的方法。就我而言,源是array的结果,它保留了原始数据类型,因此减少了插入错误。

再次如OP的评论所述,他正在根据Invoke-Sqlcmd而不是columns解析值。这也可能导致错误。例如,还有一种在使用rows语句的表中插入值的方法。请注意,INSERT SQL Server语句在行级而不是列级别上插入值。在这种情况下,解析值INSERT可能会失败。