我制作了一个程序,将库存信息从PowerShell脚本输入到数据库。
除了一件事,一切都在顺利执行。每当我运行脚本时,我都需要将值从一个表复制到另一个历史表,然后从第一个表中删除旧条目,以便它只有通过PowerShell脚本的最新值扫描条目。但是当我执行它时,只有最后一个条目出现在第一个表中,所有条目都被发送回历史表。这是一个逻辑错误。
请你纠正我,这样当我运行脚本时,所有条目都出现在第一个表中,只有我上次运行脚本时的条目转到另一个表?或者我是否需要为它创建一个新程序,我在PowerShell循环执行之前只运行一次?
存储过程:
DELIMITER $$
DROP PROCEDURE IF EXISTS `e_inv`.`insertvalue` $$
CREATE PROCEDURE "insertvalue"(
IN assetname_in varchar(255),
IN attributename_in varchar(255),
IN entry_in varchar(255),
IN val_in int,
IN sc varchar(255),
IN ip varchar(255)
)
BEGIN
DECLARE temp_id INT;
DECLARE temp_u_id INT;
INSERT INTO attribute_value_history
SELECT * FROM attribute_value;
DELETE FROM attribute_value;
SELECT u.u_id INTO temp_u_id
FROM user_system_map u
WHERE u.ip_add=ip;
SELECT a.map_id INTO temp_id
FROM asset_attribute_map a
INNER JOIN asset_master b ON a.asset_id=b.asset_id
INNER JOIN attribute_master c ON a.attribute_id=c.attribute_id
WHERE b.asset_name=assetname_in
AND c.attribute_name=attributename_in;
INSERT INTO attribute_value (
map_id,
entry,
u_id,
value_id,
scan_time
) VALUES (
temp_id,
entry_in,
temp_u_id,
val_in,
cast(sc as datetime)
);
END $$
DELIMITER ;
PowerShell代码:
cls
$MySQLAdminUserName = 'root'
$MySQLAdminPassword = 'root'
$MySQLDatabase = 'e_inv'
$MySQLHost = 'egovpc3'
$ConnectionString = "server=" + $MySQLHost + ";port=3306;uid=" +
$MySQLAdminUserName+ + ";pwd=" + $MySQLAdminPassword +
";database="+$MySQLDatabase
[void][System.Reflection.Assembly]::LoadWithPartialName("MySql.Data")
$Connection = New-Object MySql.Data.MySqlClient.MySqlConnection
$Connection.ConnectionString = $ConnectionString
$Connection.Open()
$SqlCommand = New-Object MySql.Data.MySqlClient.MySqlCommand
$arr=get-content -path "D:\Powershell\New Folder\a.txt"
foreach($comp in $arr) {
$ip=([System.Net.Dns]::GetHostAddresses($comp) |select $_.ToString)
$count=0
$bios=gwmi Win32_UserAccount -computername $comp -authentication packetprivacy
# $date = Get-Date -format "yyyy-MM-dd HH:MM:ss"
# $date
foreach($obj in $bios) {
$count=$count+1
$Manufacturer=$obj.Manufacturer
$Name=$obj.Name
#$ReleaseDate=$obj.ConvertToDateTime($obj.ReleaseDate)
#$SerialNumber=$obj.SerialNumber
#$Version=$obj.Version
$date = Get-Date -format "yyyy-MM-dd HH:mm:ss"
$date
$SqlCommand.CommandText =
"call insertvalue('UserAccount','Name','$Name','$count','$date','$ip')"
$SqlCommand.Connection = $Connection
$SqlCommand.ExecuteNonQuery()
}
}
编辑:我还想知道如果出现任何问题并且未保存历史记录,如何为此过程部署ROLLBACK
语句。
答案 0 :(得分:0)
您的活动表仅保留最后一条记录,因为您在循环中多次调用存储过程,因此每次将所有当前存在的记录(包括在上一次迭代中添加的记录)移动到历史记录表中。你是的,你应该将你的存储过程拆分为两个:一个用于将现有记录移动到历史表(在启动循环之前只调用一次),另一个用于将新记录添加到活动表(在内部调用循环)。
至于能够回滚操作:您需要将语句封装在事务中:
...
$Connection.Open()
$IsolationLevel = [System.Data.IsolationLevel]::ReadCommitted
$Transaction = $Connection.BeginTransaction($IsolationLevel)
$SqlCommand = New-Object MySql.Data.MySqlClient.MySqlCommand
$SqlCommand.Connection = $Connection
$SqlCommand.Transaction = $Transaction
...
$SqlCommand.CommandText = "..."
$SqlCommand.ExecuteNonQuery()
...
$Transaction.Commit()
...
要回滚交易,请使用$Transaction.Rollback()
代替$Transaction.Commit()
,例如在异常处理程序中:
$ErrorActionPreference = "Stop"
try {
$Transaction = $Connection.BeginTransaction($IsolationLevel)
...
$Transaction.Commit()
} catch {
$Transaction.Rollback()
}