如何只更新Powershell中现有日期变量的年份?我一直在尝试更新PowerShell日期变量的年份,但尚未成功。
我尝试发布最小代码,根据一些答案,我发现我发布的代码太小了。我没有在任何地方的实际代码中使用GetDate。我有几个年份无效的日期,比如1058年,还有一些日期是1059年。这些都需要更新到有效年份,我选择将它们更新到1900年,但我不知道如何做到这一点。
PS > $DateUpdateYear = Get-Date # This is actually a date in a csv file imported into PowerShell using Import-Csv. I have 73k records and one column has bad dates. I need to find these bad dates less than the year 1900 and update them to 1900.
PS > $DateUpdateYear.Year
output > 2023
PS > $DateUpdateYear.Year = 1900
output > InvalidOperation: 'Year' is a ReadOnly property
每次我在谷歌上搜索如何设置年份时,我都会继续获得set-Date cmdlet的结果,每次我阅读set-Date的文档时,我没有看到任何关于设置现有日期的年份的信息。
我决定尝试一种看起来“太好了,不可能是真的”的尝试,只需使用
$DateUpdateYear.Year = 1900
但是,当尝试执行此操作时,错误会指出属性为只读。
TL;DR------------------------------------------------------------TL:DR
此答案已成功回答,为了帮助任何其他可能希望在导入SQL Server(Express/AAzure)之前通过循环更新日期字符串的人,下面将向您展示如何实现这一点,并展示如何克服将数据导入SQL Server/AAzure的其他一些障碍。
有三个主要问题需要克服,它们如下:
-
行尾字符是换行符。以新行作为行尾字符的导出文件在基于Linux的系统中是典型的。我发现很多工具都讨厌换行,所以Powershell脚本的第一步是将EOL换行替换为标准的回车换行。LF->CRLF
-
下一个问题是,导入的文件需要一个列来表示“标识列”的占位符。我希望/需要导入后的每个记录都有一个唯一的键,因此这可以通过简单地创建带有Identity Column的表来实现。我遇到的问题是,要导入的csv/tsv文件仍然需要在文件中包含标识列。如果不在“格式文件”中提供此列的知识,我就无法导入它,因此也无法导入文件。
-
我需要解决的最后一项问题是执行一些导入前的数据操作。SQL Server日期有一个限制,它们支持的最早日期是1753年。我的档案中有几个日期是1753年之前的年份,这导致整个记录都失败了。这篇文章和它的答案就是这个最后问题的解决方案。现在,我已经掌握了如何读取和更新这些PowerShell对象中的数据的循环和知识,我可以使用它来更新任何坏数据或执行任何类型的导入前分析。
PowerShell导入脚本
#-Import TAB Delimited File (SQL Express and Azure Examples)
#-Declare File Paths
$SourceFile = "TAB_Delimited.tsv"
$ExportFile = "TAB_Updated.tsv"
$FormatFile = "TAB_Delimited.fmt"
$ErrorFile = "TAB_Delimited_Errors.log"
#---------- 1 Add Column to the beginning of the CSV/TSV file for the Identity Column. The Export-Csv Commandlet by default also Replaces NewLine_LF (\n) with Cariage Return Line Feed CRLF (\r\n)
#-The main purpose of the below is to add a Column at the beginning of the file as a placeholder for the Identity Column in the Staging Table.
#-The below will read the Tab Delimited file having EOL Characters as New Lines/Line Feeds \n and turn them into CRLF (Cariage Return, Line Feeds) \r\n.
#-It will also remove almost all of the double quotes it finds in the file. The -UseQuotes option is not perfect and so we still have to clean
#- up the data Post Import and remove any Leading or Trailing Double Quotes using a SQL Update.
Import-Csv $SourceFile -Delimiter "`t" |
Select-Object @{Name='_record_number';Expression={'999'}},* | #-Example Adding new column to End Select-Object *,@{Name='column3';Expression={'setvalue'}}
ForEach-Object {
if ( (![string]::IsNullOrEmpty($_.client_dob)) -and ([datetime]$_.client_dob -lt (Get-Date 1900-01-01) ) ) {
$_.client_dob = (Get-Date $_.client_dob -Year 1900).ToString('yyyy-MM-dd')
#-Write-Host $_.pcc_id $_.client_dob
}
$_
} |
Export-Csv $ExportFile -Delimiter "`t" -UseQuotes Never -NoTypeInformation
#---------- 2 Import TAB Delimited File Using Format File ---------------
$global:pass = "password"
#-Use an Import File to Bulk Import Data
bcp Database.Schema.Table IN $ExportFile `
-f $FormatFile `
-e $ErrorFile `
-S LOCALSERVERPC\SQLEXPRESS `
-U sa -P $pass `
-F 2 `
#-L 1000
----------- Or using Azure with Trusted Auth follow the below example ----------------------
#-Use an Import File to Bulk Import Data into Azure
bcp Database.Schema.Table IN $ExportFile `
-f $FormatFile `
-e $ErrorFile `
-S Server_Name_Here `
-T `
-F 2 `
#-L 2000