IF SQL #ID EXISTS, DO NOT INPUT? - sql

I made a Powershell script that inputs data from a Powershell O365 Health Module into a SQL Database by using a Foreach loop. The issue I am having now is that each time I run the script (every 30 minutes or something), it creates new lines into my database, and most of the time it's duplicates.
One of the values (#ID) is unique, so what I want to do is:
If #ID FROM table exist, DO Nothing. So it should then only skip that line in the Foreach statement and continue into the next one and continue writing the others into the table.
I am kinda new to SQL so I am a bit unsure how to do this.
Here's my script:
$o365user = 'user#company.com'
Import-Module O365ServiceCommunications
$Credential = Get-Credential $o365user
$Session = New-SCSession -Credential $Credential -locale en-US
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection;
$SqlConnection.ConnectionString = 'Server=testcoresight;Database=O365Health;Integrated Security=True'
$SqlConnection.Open();
$sql = #'
INSERT INTO O365Events(
StartTime,
EndTime,
ID,
EventType,
Service,
Status
)
VALUES (
#StartTime,
#EndTime,
#ID,
#EventType,
#Service,
#Status
)
'#
$cmd = $SqlConnection.CreateCommand()
$cmd.CommandTimeout = 15
$cmd.CommandText = $sql
[void]$cmd.Parameters.Add('#StartTime',[string])
[void]$cmd.Parameters.Add('#EndTime',[string])
[void]$cmd.Parameters.Add('#ID',[string])
[void]$cmd.Parameters.Add('#EventType',[string])
[void]$cmd.Parameters.Add('#Service',[string])
[void]$cmd.Parameters.Add('#Status',[string])
#Gets O365 Health Status. Shows Incident types for the past 7 days and sends them to the SQL DB.
Get-SCEvent -SCSession $Session -EventTypes Incident -pastdays 7 |
ForEach-Object {
Try{
$cmd.Parameters['#StartTime'].Value = if($_.StartTime){$_.StartTime}else{''}
$cmd.Parameters['#EndTime'].Value = if ($_.EndTime) { $_.EndTime } else { '' }
$cmd.Parameters['#ID'].Value = if ($_.ID) { $_.ID } else { '' }
$cmd.Parameters['#EventType'].Value = if ($_.EventType) { $_.EventType } else { '' }
$cmd.Parameters['#Service'].Value = if ($_.AffectedServiceHealthStatus.ServiceName) { $_.AffectedServiceHealthStatus.ServiceName } else { '' }
$cmd.Parameters['#Status'].Value = if ($_.Status) { $_.Status } else { '' }
Write-Host ID Loaded: $_.ID -ForegroundColor green
if ($cmd.ExecuteNonQuery() -ne 1) {
Write-Host Insert failed: $_.ID
}
}
Catch{ Write-Host $_ }
}
$SqlConnection.Close()
What I believe I have to do is add something like:
IF #ID EXISTS FROM O365Events skip

INSERT INTO O365Events(
StartTime,
EndTime,
ID,
EventType,
Service,
Status
)
SELECT
#StartTime,
#EndTime,
#ID,
#EventType,
#Service,
#Status
WHERE NOT EXISTS (SELECT null FROM O365Events WHERE ID = #ID)
Or, really, you could just make the ID the promary key and handle the error that occurs when you try to insert a duplicate

Related

Date Variable is not Carry Over to Function for Query String

I receive this error:
ExecuteSqlQuery : Must declare the scalar variable "#date".
I call the query as such: ExecuteSqlQuery -server "sqlbox" -database "dbname" and I receive the date variable error. You can see my query statement uses the variable m.created_date >= #date.
How do I correctly pass the date variable to query string so it runs in the function without an issue? NOTE: the code works when I hardcode the date value.
Function ExecuteSqlQuery {
Param(
[Parameter(Mandatory=$true)][string]$server,
[Parameter(Mandatory=$true)][string]$database
)
Process
{
$date= $((get-date).AddSeconds(-120).ToString("MM-dd-yyyy HH:mm:ss"))
$getscriptinfo = "select m.created_date, a.engine_full_hierarchy as Location, e.exciter_name, e.engine_exciter_id as ExciterID, m.additional_data as ReasonDown from HugsAdminAmador.mv_audit m, HugsAdminAmador.exciter e, HugsAdminAmador.area_map a where m.object_id = e.exciter_id and e.area_map_id = a.area_map_id and m.created_date >= #date and m.additional_data like '%NewStatus=DOWN%' and m.additional_data not like '%autonomous%'"
$scriptscon = New-Object System.Data.SqlClient.SqlConnection
$scriptscon.ConnectionString = "Data Source=$server;Initial Catalog=$database;Integrated Security=true"
$scriptcmd = New-Object System.Data.SqlClient.SqlCommand
$scriptcmd.Connection = $scriptscon
$scriptcmd.CommandText = $getscriptinfo
$scriptcmd.CommandTimeout = 0
$ErrorActionPreference = 'Stop'
try
{
$scriptscon.Open()
$Reader = $scriptcmd.ExecuteReader()
# if reader returns data create an array of the error data for the potential alert.
If ($Reader.HasRows) {
$obj = $Reader | foreach {
$row = $_;
#the left naming is for the column headers in the email.
new-object psObject -Property #{
CreateDate = $row.Item("created_date")
ReasonDown = $row.Item("ReasonDown")
ObjectID = $row.Item("object_id")
}
}
}
return $obj
}
catch [Exception]
{
# Write-Warning "Get-ExecuteScripts (Connection: [$server].[$database])"
# Write-Warning $_.Exception.Message
# Write-Warning "Query: $getscriptinfo --Id $scriptid"
Write-Error $_
$ErrorEvent = #{
LogName = 'Exciter_Log'
Source = 'Exciter_Health'
EventID = 333
EntryType = 'Information'
Message = $_
}
Write-EventLog #ErrorEvent
}
finally
{
$ErrorActionPreference = 'Continue'
$scriptscon.Dispose()
$scriptcmd.Dispose()
}
}
}

How can I add to an existing value in sql table

How can i add a value to an existing value in SQL example a value 4 in a column how can i add 2 to it to make it 6 not to update to 2 but to add the previous value and the new value to together here is my class php file
<?php
class data
{
public $d_count;
public $id;
private $conn;
private $table_name;
public function __construct($db)
{
$this->conn = $db;
$this->table_name= "tbl_data";
}
public function updateCount()
{
// $query = "UPDATE tbl_data SET d_count = ?, date_updated = ? WHERE id = ?";
$query = "UPDATE tbl_data SET d_count '+1' = ?, date_updated = ? WHERE id = ?";
$obj = $this->conn->prepare($query);
$this->d_count = htmlspecialchars(strip_tags($this->d_count));
$this->date_updated = htmlspecialchars(strip_tags($this->date_updated));
$this->id = htmlspecialchars(strip_tags($this->id));
$obj->bind_param("sss", $this->d_count, $this->date_updated, $this->id);
if ($obj->execute()) {
return true;
}
return false;
}
}
The line I commented out is what i used to test the code and it works fine but now i need to add the old value + new value together here is the code am using to update the table
<?php
$data = new data($connection);
if($_SERVER['REQUEST_METHOD'] === "POST"){
$newDCount = json_decode(file_get_contents("php://input"));
if(!empty($newDCount->d_count))
$data->id= $newDCount->id;
$data->d_count = $newDCount->d_count;
$data->date_updated = date('Y-m-d H:i:s', time());
if($apiata->updateCount()){
http_response_code(200);
echo json_encode(array(
"status" => 200,
"message" => "Success"
));
}
else
{
http_response_code(200);
echo json_encode(array(
"status" => 500,
"message" => "Failed"
));
}
}
To update the d_count to add to the existing d_count value, the query should look like:
$sql = 'UPDATE catalog SET d_count = d_count + ?, date_updated = ? WHERE id = ?';
The other handling should be ok as-is.

PDO -> if(table exist)

try {
$query = $pdo->query("SELECT 1 FROM `classes` LIMIT 1");
} catch (Exception $e) {
$query = $pdo->prepare("CREATE TABLE `classes`(
`ID_class` int(11) AUTO_INCREMENT,
`name` varchar(255),
PRIMARY KEY(`ID_class`))");
$query->execute();
}
Hello.
It doesn't catch, if the table doesn't exist.
This is not going to work because, according to the PHP documentation (php.net):
Return Values
PDO::query() returns a PDOStatement object, or FALSE on failure.
So you either need to test if $pdo->query("SELECT 1 FROM 'classes' LIMIT 1") returns false or an alternative like checking if a table exists without using 'select from' (stackoverflow.com).
It worked for me with the PDO ATT_ERRMODE set to ERRMODE_EXCEPTION.
$user = 'test';
$pass = 'test';
$opt = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION];
$db = new PDO('mysql:host=localhost;dbname=test;charset=utf8' ,
$user ,
$pass ,
$opt
);
try {
$query = $db->query("SELECT 1 FROM `classes` LIMIT 1");
} catch (Exception $e) {
$query = $db->prepare("CREATE TABLE `classes`(
`ID_class` int(11) AUTO_INCREMENT,
`name` varchar(255),
PRIMARY KEY(`ID_class`))");
$query->execute();
}

Retrieving a int value from database

I am trying to get sender_id and receiver_id into my variables but it is giving me following error
Warning: mysql_fetch_array() expects parameter 1 to be resource,
object given in /opt/lampp/htdocs/Task/php/insertdatanew.php on line
36
Warning: mysql_fetch_row() expects parameter 1 to be resource, object
given in /opt/lampp/htdocs/Task/php/insertdatanew.php on line 42 N
CODE:
<?php
$sender_id = 0;
$receiver_id = 0;
session_start();
if(isset($_SESSION['login_user'])) {
//header('location: chat.php');
}
else {
header('location: chatlogin.php');
}
if(isset($_REQUEST['sender']) AND isset($_REQUEST['msg']) AND isset($_REQUEST['time']) AND isset($_REQUEST['receiver']) ){
$msg = $_REQUEST['msg'];
$time = $_REQUEST['time'];
$sender = $_REQUEST['sender'];
$receiver = $_REQUEST['receiver'];
echo $sender;
echo $receiver;
echo $msg;
echo $time;
//echo $msg;
if ( empty($_REQUEST['msg']) ) {
}
else{
require_once 'dc_chat.php';
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$result = $mysqli -> query("SELECT id from users where username LIKE '{$sender}'");
$row = mysql_fetch_row($result);
$sender_id = $row[0];
$result = $mysqli -> query("SELECT id from users where username LIKE '{$receiver}'");
$row = mysql_fetch_row($result);
$receiver_id = $row[0];
//echo $receiver_id;
$sql = $mysqli -> query("INSERT INTO `messages` (`sender_id`, `receiver_id`, `msg`, 'chattime') VALUES ('{$sender_id}', '{$receiver_id}', '{$msg}' ,'{$time}')");
if(! $sql ) {
echo 'N';
}
else {
echo 'Y';
}
}
}
else{
echo "hello";
}
?>
I am getting $msg, $time, $sender, $receiver from a ajax and datatype is JSON
You are mixing mysql and mysqli functions. mysql_fetch_row should probably be mysqli_fetch_row.
Replace if (!$sql) with if ($mysqli->affected_rows == 0) to test for success on the INSERT statement.
If you suspect an error in your SQL statement use echo $mysqli->error; after your query line to put that on the screen.

perl dbi rollback not working

i am using this approach. If there is an error in the sql, rollback only happens for the first id of the asset_group. Rest of the ids are ignored. Am i doing it the right way?
my $sql = "sql batch that update and insert depending on the condition";
$dbh->{RaiseError} = 1;
$dbh->{PrintError} = 0;
$dbh->{AutoCommit} = 0;
my $sth = $dbh->prepare($sql);
my #error = ();
my $num = 0;
foreach my $id (#asset_group) {
next if ($id eq '');
eval {
$sth->bind_param(1, $id);
$sth->bind_param(2, $vars{'other_id'});
$sth->execute();
};
if ($#) {
$dbh->rollback();
push #error, $#
} else {
$dbh->commit();
}
}
Depending on the database, you may need to issue a begin work before you start changing things. I seem to remember Informix requiring one.
Also, it looks like you are issuing a commit or a rollback after each execute. Once you commit, you can't rollback. Normally one says something like
$dbh->begin_work;
eval {
for my $id (#asset_group) {
next if ($id eq '');
$sth->execute($id, $vars{other_id});
}
1; #if it doesn't die then this will force it to return true
} or do {
my $error = DBI->errstr;
$dbh->rollback();
die "could not insert rows: $error\n"
};
$dbh->commit();
Note how I don't use $#. $# is untrustworthy.