How to Automatically Import Data to a SQL Server?

I haven’t worked with MySQL since college and even then what I would like to do was not something we discussed.

At my work we do some computer refurbishment. This requires the documentation of computer hardware into a database as it is received and processed.

I have already developed a piece of software that runs on a SMB share which the computer connects to. This asks the computer for a long list of information. This information is compared against tables of known hardware and automatically generates a complete system report so we don’t have to document the hardware manually anymore. Example below.

DateImaged      : 08/09/2024 10:26
SerialNumber    : 1234567890
Model           : FZ-55
PartNumber      : FZ-55C9-00VM
MFRDate         :
Condition       : NO AUDIT
Processor       : CORE i7 8665U 1.90
Memory          : 16384
HardDrive       : 512 SSD
OpticalDrive    :
FloppyDrive     :
OperatingSystem : WIN 11 PRO 64
NetworkCard     : GIGABIT
Controller      : SATA
Wireless        : A/B/G/N/AC
VideoCard       : INTEL UHD GRAPHICS 620-128MB
USB             : 2xUSB,1xUSB-C
Firewire        :
Bluetooth       : YES
Battery         : 2xHOLDS CHARGE
Power           : AC
Screen          : 14 1920x1080
Touchscreen     : YES
PageCount       :
JetDirect       :
Consumables     : POWER ON HOURS: 6240
PaperTray       :
Other1          : HDMI,BACKLIT KEYBOARD
Other2          : WEBCAM,STYLUS,SIERRA EM7511 X16 LTE-A
Other3          : MICROSD,SIM CARD SLOT
DetailCondition : NWT
Details         : SCUFFS ON LCD LID / SHINY KEYS / WORN PALMREST
Rebill          : 0

This was generated automatically when I ran the program on the computer.

This output is compiled into a singular line and appended into the end of a .CSV file on the SMB server. I then wrote another program in PowerShell which uses Import-Csv which lets me query all the relevant fields and import them into the company database.

Although this does work it is not an elegant solution. Ideally we would have a proper database that lets me import computers as my software runs. Instead of using .CSV files it would generate a SQL database entry and populate all of the appropriate fields.

So here is where the problem lies. I have the program. I can setup an SQL server but how do I automate connecting and uploading the data? HTTP? SSH? Somehow use an XML file? PowerShell is pretty much my only option unless there’s a SQL Library or something I can connect to my program and write the code from there. What options do I have available to me to connect and add an entry? The tricky bit is I cannot install any additional software on these clients.

1 Like

Create a web service/application. Your client application calls the web service to submit information. The web service processes the information and inserts into data base.

2 Likes

In college we used PHP as a middle man between a HTTP user interface and performing table queries that would show us what is in the tables and let us add/remove entries.

If HTTP is generally the way to go then I just need to figure out how the heck I make a HTTP request from my program and perform the submission. Don’t know if SQL can respond to HTTP directly or if I will have to dabble in PHP again and figure out how to insert the data into the submission.

I love how the goal sounds simple enough but I know figuring out the programming side is going to be hell and a half. :laughing:

What language is your application written in? I don’t feel like your solution is bad by any means. It seems like the main issue is the automation?

Couldn’t you set up a job and just batch insert into your SQL database every X minutes/hours then truncating or moving the CSV records to bulk storage associated with the batch (in case you might way to maintain source data harvested by your application)?

Seems like that might be the easier solution based on your constraints.

1 Like

It highly depends on your skill set. If you never had experience about writing a web application, it may take you a month to sort everything out.
If you can just use shell scripts to compile everything into one csv file on the shared network drive and write a simple application to load it and insert into database, it is not a bad solution.

1 Like

Personally, the easiest thing I can think of would to just write a quick python script that will connect and insert into your MySQL database, that looks into a specific directory and is run automatically by the task scheduler every X minutes.

While you could do some web based thing, unless you really want to spend time maintaining that its better to keep it as simple as possible.

Or you could just install Ansible or Saltstack on every machine and then just automate dumping the output into the database (facts or grains, respectfully). This is what I would recommend if you want to take it a step deeper but is the most robust long term because then you can do other things easily.

1 Like

That was what I was thinking as well but the OP said that he can’t install any additional software so figured python was off the table. Totally agree that would be the easiest solution as well if it’s feasible.

Ah granted I skimmed. You can bundle python to make it portable so its not technically ‘installed’ but I get your point. Might not fly by Security.

So if powershell is on the table then I did a quick DDG and seems that there is a build-in connector module available to use.

So there we go.

1 Like

This one:

will also give you an intermediate solution to go from your existing csv format to uploading data to the database …

1 Like

obligatory

exploits_of_a_mom

3 Likes

For a (probably too complex) solution that still does not involve installing software on the clients, you could also deploy something like

on top of you mysql/mariadb database, this would implement a RESTful API interface to the database so that you could then use curl or the powershell equivalent to push/pull data …

I did not expect this much assistance to happen. :sweat_smile: Thank you.

@bytedotio My program is written in C# and is a CLI application that relies on the .NET Framework 4.8.1. This was an easy pick because 4.8.1 comes pre-installed on every copy of Windows we deploy.

What you suggest is something I have thought about. My research tells me MySQL is compatible with .CSV files for import/export. The problem IS more over server-side where I just have piles of .CSV files filled with computers and no real organization other than naming each CSV file the date it was created.

Instead of over-hauling the existing software infrastructure I could have a hourly or nightly cronjob run that imports every given days .CSV file into a table. I will still have to re-learn how to use MySQL though that’s fine.

It might still be worthwhile to investigate HTTP because that would permit me to create a simple strait-forward interface to make queries either by date or by serial number so I have a way to look-up the data I put in because right now I just open PowerShell and use findstr and tell it 123xyz serial number /in/this/directory/*.csv. It works…but I hate it.

@jxdking This is a bit of a play on bytedotio’s idea. Some important details I should have mentioned is that the SMB server and if we can make it work a MySQL server both run in Linux LXC Containers on a PROXMOX hypervisor. With direct access to the data files on the network share writing a program to manipulate said data might not be necessary. We could theoretically import the files direct to SQL using scripts.

As for my skillset…it’s like swiss cheese. Lots of holes and everything I do is something new I’m learning.

@Dynamic_Gravity bytedotio is correct. This issue in more details is we do computer re-sale. They’re never the same computer that we process. We don’t own them, it is a revolving door of new computers. The most I install is a temporary batch script that initializes the connection to the SMB server which runs the post-install script hosted on the server then deletes itself. Otherwise these have to stay untouched clean installs of Windows 10 & 11.

@MadMatt While I can invoke a administrative level powershell and pass commands into it through my C# application which would have direct access to all the string variables containing what I want to upload I’m looking at Install-Module CSVCmdlets and if that’s needed but not pre-installed on the client I have to avoid this idea. If I installed any additional packages on the PC’s I’d have to remove them immediately after.

I could host a Windows VM on the server and have it work as an intermediary by reading the .CSV files that already get compiled and upload them that way but I think there’s a more direct solution.

@TryTwiceMedia Ha, SQL injection. Always pharse your inputs.

Addressing everybody I think I’m going to start by setting up and re-familiarizing myself with MySQL. I know I saw commands for importing CSV files and that could be the simplest solution because the logging here is archival.

Where I will probably look next is how to build (again) a web page that can read the database and let me query things like serial numbers across multiple tables.

1 Like

Progress on this has been going alright. I found a nice little tutorial to re-introduce me to HTML, PHP, and SQL.

This covers all the basics. Creation, Deletion, Query, and Updating. It took me two days but I got their example working and today I got it half working with a snippit of our actual database. It still has a long ways to go, I got stuck several times and had 100 browser tabs open and still had to do some trial and error but we’re getting there.

This gives me an easy to use WebUI for look up queries. I figured out the command needed to import .CSV files. That’s a mess. I will have to figure out how to make it execute from a cronjob.

1 Like

@jxdking @bytedotio @Dynamic_Gravity @MadMatt @TryTwiceMedia

So I implemented a solution and was curious to hear feedback regarding if there’s ways I could improve or optimize it. It’s HTML/PHP/SQL + Cronjobs.

I’m just going to go in the order of operation. First thing is I made a cronjob. This pulls the latest database.CSV file from the SMB server and puts it in the mysql-files working directory. Then imports the file to the database table.

0 22 * * * /root/sql-log.script

rsync -avhP -e ‘ssh -p 22’ [email protected]:/mnt/images/windows/database.csv /var/lib/mysql-files/
mysql -e “source /root/sql-query.sql”
rm /var/lib/mysql-files/database.csv

I had to put the actual SQL query in an external file because it uses a quotation mark which ruins using mysql -e " " directly.

Contents of sql-query.sql:
load data infile '/var/lib/mysql-files/database.csv' into table computers.windows fields terminated by ',' enclosed by '"' lines terminated by '\n' ignore 1 rows (DateImaged,SerialNumber,Model,PartNumber,MFRDate,Condition,Processor,Memory,HardDrive,OpticalDrive,FloppyDrive,OperatingSystem,NetworkCard,Controller,Wireless,VideoCard,USB,Firewire,Bluetooth,Battery,Power,Screen,Touchscreen,PageCount,JetDirect,Consumables,PaperTray,Other1,Other2,Other3,DetailCondition,Details,Rebill) set ID=null;

It’s a hideous command but it works. This then imports the CSV file into the table I created:

+-----------------+--------------+------+-----+---------+----------------+
| Field           | Type         | Null | Key | Default | Extra          |
+-----------------+--------------+------+-----+---------+----------------+
| ID              | int unsigned | NO   | PRI | NULL    | auto_increment |
| DateImaged      | varchar(16)  | YES  |     | NULL    |                |
| SerialNumber    | varchar(12)  | YES  |     | NULL    |                |
| Model           | varchar(56)  | YES  |     | NULL    |                |
| PartNumber      | varchar(48)  | YES  |     | NULL    |                |
| MFRDate         | varchar(16)  | YES  |     | NULL    |                |
| Condition       | varchar(8)   | YES  |     | NULL    |                |
| Processor       | varchar(96)  | YES  |     | NULL    |                |
| Memory          | int          | YES  |     | NULL    |                |
| HardDrive       | varchar(74)  | YES  |     | NULL    |                |
| OpticalDrive    | varchar(8)   | YES  |     | NULL    |                |
| FloppyDrive     | varchar(8)   | YES  |     | NULL    |                |
| OperatingSystem | varchar(16)  | YES  |     | NULL    |                |
| NetworkCard     | varchar(42)  | YES  |     | NULL    |                |
| Controller      | varchar(4)   | YES  |     | NULL    |                |
| Wireless        | varchar(36)  | YES  |     | NULL    |                |
| VideoCard       | varchar(96)  | YES  |     | NULL    |                |
| USB             | varchar(16)  | YES  |     | NULL    |                |
| Firewire        | varchar(8)   | YES  |     | NULL    |                |
| Bluetooth       | varchar(3)   | YES  |     | NULL    |                |
| Battery         | varchar(16)  | YES  |     | NULL    |                |
| Power           | varchar(6)   | YES  |     | NULL    |                |
| Screen          | varchar(14)  | YES  |     | NULL    |                |
| Touchscreen     | varchar(3)   | YES  |     | NULL    |                |
| PageCount       | varchar(8)   | YES  |     | NULL    |                |
| JetDirect       | varchar(8)   | YES  |     | NULL    |                |
| Consumables     | varchar(24)  | YES  |     | NULL    |                |
| PaperTray       | varchar(8)   | YES  |     | NULL    |                |
| Other1          | varchar(42)  | YES  |     | NULL    |                |
| Other2          | varchar(42)  | YES  |     | NULL    |                |
| Other3          | varchar(42)  | YES  |     | NULL    |                |
| DetailCondition | varchar(3)   | YES  |     | NULL    |                |
| Details         | varchar(64)  | YES  |     | NULL    |                |
| Rebill          | varchar(8)   | YES  |     | NULL    |                |
+-----------------+--------------+------+-----+---------+----------------+

So with that sorted I have a automated way to upload the data. Now to read the data I used HTML (Apache2) and PHP to just build a small set of web pages from scratch using the previously posted tutorial as my template.

read_empty

<?php
require "../config.php";
require "../common.php";

if (isset($_GET["ID"])) {
  try {
    $connection = new PDO($dsn, $username, $password, $options);

    $id = $_GET["ID"];

    $sql = "DELETE FROM windows WHERE ID = :ID";

    $statement = $connection->prepare($sql);
    $statement->bindValue(':ID', $id);
    $statement->execute();

    $success = "Computer successfully deleted";

  } catch(PDOException $error) {
    echo $sql . "<br>" . $error->getMessage();
  }
}

if (isset($_POST['submit']) || isset($_GET['SerialNumber'])) {
  try {

    $connection = new PDO($dsn, $username, $password, $options);

    if (isset($_POST['submit'])) {
      $sql = "SELECT * FROM windows WHERE SerialNumber = :SerialNumber";
      $SerialNumber = $_POST['SerialNumber']; }

    else {
      $sql = "SELECT * FROM windows WHERE SerialNumber = " + $_GET['SerialNumber'];
      $SerialNumber = $_GET['SerialNumber']; }

    $statement = $connection->prepare($sql);
    if (isset($_POST['submit'])) { $statement->bindParam(':SerialNumber', $SerialNumber, PDO::PARAM_STR); }
    else { $statement->bindParam($_GET['SerialNumber'], $SerialNumber, PDO::PARAM_STR); }
    $statement->execute();

    $result = $statement->fetchAll();

  } catch(PDOException $error) {
    echo $sql . "<br>" . $error->getMessage();
  }
}
?>

<?php include "templates/header.php"; ?>
<?php if ($success) echo $success; ?>
<?php
if (isset($_POST['submit']) || isset($_GET['SerialNumber'])) {
  if ($result && $statement->rowCount() > 0) { ?>
    <h2>Results</h2>

    <table>
      <thead>
        <tr>
          <th>#</th>
          <th>Date Imaged</th>
          <th>Serial Number</th>
          <th>Model</th>
          <th>Part Number</th>
          <th>MFR Date</th>
          <th>Condition</th>
          <th>Processor</th>
          <th>Memory</th>
          <th>Hard Drive</th>
          <th>Optical Drive</th>
          <th>Floppy Drive</th>
          <th>Operating System</th>
          <th>Network Card</th>
          <th>Controller</th>
          <th>Wireless</th>
          <th>Video Card</th>
          <th>USB</th>
          <th>Firewire</th>
          <th>Bluetooth</th>
          <th>Battery</th>
          <th>Power</th>
          <th>Screen</th>
          <th>Touchscreen</th>
          <th>Page Count</th>
          <th>Jet Direct</th>
          <th>Consumables</th>
          <th>Paper Tray</th>
          <th>Other 1</th>
          <th>Other 2</th>
          <th>Other 3</th>
          <th>Detail Condition</th>
          <th>Details</th>
          <th>Rebill</th>
          <th>Update</th>
          <th>Delete</th>
        </tr>
      </thead>

      <tbody>
        <?php foreach ($result as $row) { ?>
          <tr>
            <td><?php echo escape($row["ID"]); ?></td>
            <td><?php echo escape($row["DateImaged"]); ?></td>
            <td><?php echo escape($row["SerialNumber"]); ?></td>
            <td><?php echo escape($row["Model"]); ?></td>
            <td><?php echo escape($row["PartNumber"]); ?></td>
            <td><?php echo escape($row["MFRDate"]); ?></td>
            <td><?php echo escape($row["Condition"]); ?> </td>
            <td><?php echo escape($row["Processor"]); ?> </td>
            <td><?php echo escape($row["Memory"]); ?> </td>
            <td><?php echo escape($row["HardDrive"]); ?> </td>
            <td><?php echo escape($row["OpticalDrive"]); ?> </td>
            <td><?php echo escape($row["FloppyDrive"]); ?> </td>
            <td><?php echo escape($row["OperatingSystem"]); ?> </td>
            <td><?php echo escape($row["NetworkCard"]); ?> </td>
            <td><?php echo escape($row["Controller"]); ?> </td>
            <td><?php echo escape($row["Wireless"]); ?> </td>
            <td><?php echo escape($row["VideoCard"]); ?> </td>
            <td><?php echo escape($row["USB"]); ?> </td>
            <td><?php echo escape($row["Firewire"]); ?> </td>
            <td><?php echo escape($row["Bluetooth"]); ?> </td>
            <td><?php echo escape($row["Battery"]); ?> </td>
            <td><?php echo escape($row["Power"]); ?> </td>
            <td><?php echo escape($row["Screen"]); ?> </td>
            <td><?php echo escape($row["Touchscreen"]); ?> </td>
            <td><?php echo escape($row["PageCount"]); ?> </td>
            <td><?php echo escape($row["JetDirect"]); ?> </td>
            <td><?php echo escape($row["Consumables"]); ?> </td>
            <td><?php echo escape($row["PaperTray"]); ?> </td>
            <td><?php echo escape($row["Other1"]); ?> </td>
            <td><?php echo escape($row["Other2"]); ?> </td>
            <td><?php echo escape($row["Other3"]); ?> </td>
            <td><?php echo escape($row["DetailCondition"]); ?> </td>
            <td><?php echo escape($row["Details"]); ?> </td>
            <td><?php echo escape($row["Rebill"]); ?> </td>
            <td><a href="update-single.php?ID=<?php echo escape($row["ID"]); ?>">Edit</a></td>
            <td><a href="read.php?ID=<?php echo escape($row["ID"]); ?>&SerialNumber=<?php echo escape($row["SerialNumber"]); ?>">Delete</a></td>
          </tr>
        <?php } ?>
      </tbody>
    </table>
  <?php } else { ?>
    > No results found for <?php echo escape($_POST['SerialNumber']); ?>.
  <?php }
} ?>
    <h2>Find computer based on serial number</h2>

    <form method="post">
        <label for="SerialNumber">Serial Number</label>
        <input type="text" id="SerialNumber" name="SerialNumber">
        <input type="submit" name="submit" value="View Results">
    </form>

    <a href="index.php">Back to home</a>

    <?php include "templates/footer.php"; ?>

So HTML talks to PHP which talks to SQL and lets me run lookup queries on the uploaded .CSV files.


Right now I’m more worried about working proof-of-concept so there’s virtually nothing to the webpage but the data.

Going off the right of the screen is the option to let me edit and delete the entry. Delete only half works correctly right now but it’s a work in progress…

Today I did a bunch of reading up on .CSS and stylesheets so I was able to fix the layout just a little bit and also made my own dark mode.

If I want to view/edit the entry It lets me look at the data vertically.

<?php

/**
  * Use an HTML form to edit an entry in the
  * users table.
  *
  */

require "../config.php";
require "../common.php";

if (isset($_POST['submit'])) {
  try {
    $connection = new PDO($dsn, $username, $password, $options);
    $computer =[
      "ID"              => $_POST['ID'],
      "DateImaged"      => $_POST['DateImaged'],
      "SerialNumber"    => $_POST['SerialNumber'],
      "Model"           => $_POST['Model'],
      "PartNumber"      => $_POST['PartNumber'],
      "MFRDate"         => $_POST['MFRDate'],
      "Condition"       => $_POST['Condition'],
      "Processor"       => $_POST['Processor'],
      "Memory"          => $_POST['Memory'],
      "HardDrive"       => $_POST['HardDrive'],
      "OpticalDrive"    => $_POST['OpticalDrive'],
      "FloppyDrive"     => $_POST['FloppyDrive'],
      "OperatingSystem" => $_POST['OperatingSystem'],
      "NetworkCard"     => $_POST['NetworkCard'],
      "Controller"      => $_POST['Controller'],
      "Wireless"        => $_POST['Wireless'],
      "VideoCard"       => $_POST['VideoCard'],
      "USB"             => $_POST['USB'],
      "Firewire"        => $_POST['Firewire'],
      "Bluetooth"       => $_POST['Bluetooth'],
      "Battery"         => $_POST['Battery'],
      "Power"           => $_POST['Power'],
      "Screen"          => $_POST['Screen'],
      "Touchscreen"     => $_POST['Touchscreen'],
      "PageCount"       => $_POST['PageCount'],
      "JetDirect"       => $_POST['JetDirect'],
      "Consumables"     => $_POST['Consumables'],
      "PaperTray"       => $_POST['PaperTray'],
      "Other1"          => $_POST['Other1'],
      "Other2"          => $_POST['Other2'],
      "Other3"          => $_POST['Other3'],
      "DetailCondition" => $_POST['DetailCondition'],
      "Details"         => $_POST['Details'],
      "Rebill"          => $_POST['Rebill'],
    ];

    $sql = "UPDATE computers.windows
    SET ID = :ID,
        DateImaged = :DateImaged,
        SerialNumber = :SerialNumber,
        Model = :Model,
        PartNumber = :PartNumber,
        MFRDate = :MFRDate,
       `Condition` = :Condition,
        Processor = :Processor,
        Memory = :Memory,
        HardDrive = :HardDrive,
        OpticalDrive = :OpticalDrive,
        FloppyDrive = :FloppyDrive,
        OperatingSystem = :OperatingSystem,
        NetworkCard = :NetworkCard,
        Controller = :Controller,
        Wireless = :Wireless,
        VideoCard = :VideoCard,
        USB = :USB,
        Firewire = :Firewire,
        Bluetooth = :Bluetooth,
        Battery = :Battery,
        Power = :Power,
        Screen = :Screen,
        Touchscreen = :Touchscreen,
        PageCount = :PageCount,
        JetDirect = :JetDirect,
        Consumables = :Consumables,
        PaperTray = :PaperTray,
        Other1 = :Other1,
        Other2 = :Other2,
        Other3 = :Other3,
        DetailCondition = :DetailCondition,
        Details = :Details,
        Rebill = :Rebill
    WHERE ID = :ID";

  $statement = $connection->prepare($sql);
  $statement->execute($computer);
  } catch(PDOException $error) {
      echo $sql . "<br>" . $error->getMessage();
  }
}

if (isset($_GET['ID'])) {
  try {
    $connection = new PDO($dsn, $username, $password, $options);
    $id = $_GET['ID'];
    $sql = "SELECT * FROM windows WHERE ID = :ID";
    $statement = $connection->prepare($sql);
    $statement->bindValue(':ID', $id);
    $statement->execute();

    $computer = $statement->fetch(PDO::FETCH_ASSOC);

  } catch(PDOException $error) {
      echo $sql . "<br>" . $error->getMessage();
  }
} else {
    echo "Something went wrong!";
    exit;
}
?>

<?php require "templates/header.php"; ?>

<?php if (isset($_POST['submit']) && $statement) : ?>
  <?php echo escape($_POST['Model']); ?> successfully updated.
<?php endif; ?>

<h2>Edit Computer</h2>

<form method="post">
    <?php foreach ($computer as $key => $value) : ?>
      <input type="text" name="<?php echo $key; ?>" id="<?php echo $key; ?>" size="27" value="<?php echo escape($value); ?>" <?php echo ($key === 'id' ? 'readonly' : null); ?><label for="<?php echo $key; ?>"> - <?php echo ucfirst($key); ?></label><br>
    <?php endforeach; ?>
    <br>
    <input type="submit" name="submit" value="Submit">
</form>

<a href="index.php">Back to home</a>

<?php require "templates/footer.php"; ?>

So with this data imports automatically, and I can Read/Update/Delete data just by going to this self-hosted website.

Just yesterday I imported our full back-log of computers which amounted to a little over 10,000 machines for the year so far. We will probably be close to 20,000 computers logged by years end.

Thoughts? Anything I should tweak? Anything obvious I should have done better?

For starters you should index the serial number since that is what you’re primarily searching by and its under 20 chars so perf would be much better if you do this.

Also you should add the unique constraint.

1 Like

Now that you have php to query and update the database I’d take the last step and get rid of the whole csv part. The application that creates the csv can probably just as easily post the data directly to php to do the insert. This would make it easy to handle cases like serial numbers already existing in the database and would also make using field types other than varchar that may be more appropriate easier. It would also eliminate the delay between csv creation and the next cron job.

I’m not sure I fully understand your setup though so maybe going the csv route is needed for some reason…

You may want to also add a real datetime field set to UTC_TIMESTAMP() when you insert each new record as these tend to come in handy for a pretty wide range of reasons.

@Dynamic_Gravity I will read into index. I don’t know how to assign that but if this is my command SELECT * FROM windows WHERE SerialNumber = :SerialNumber I guess with no set index it’s reading every field in every row, pulling every S/N, then searching that list? So it’s a efficiency thing. Am I understanding this correctly?

Will enabling Index be enough or do I need to modify my query command too?

As far as adding the unique constraint goes we do sometimes have computers pass through more than once and we do want to see a history of hardware changes so duplicates are needed but I should add unique constraint to the ID column. That’s supposed to be the unique identifier for every entry. Will address that.

@tk11 The application that creates the .CSV is a self-made C# application. The program creates a string array that composes the .CSV lines. If I had any idea how to make C# talk to PHP over HTML it would be possible to port the array directly into the database but I need a way to get feedback that it was successfully entered and that confirmation would be a whole other challenge to code. I have never tried this before.

It’s easier just to use PowerShell Import-Csv and load the database.csv file then search for the computer S/N. If yes, it entered the computer to the .CSV file, if no, something went wrong and I need to manually intervene.

I will think about adding a timestamp column though for right now it’s not hard to figure out when the bulk import took place for each batch. If I did find a way to eliminate .CSV the DateImaged column would timestamp down to the minute when it was entered so I don’t think it’s needed.

Better error handling is actually a reason to communicate directly vs using csv as an intermediary because instead of just dropping the data off in hopes that it gets imported at some point in the future your application gets immediate confirmation. You’re also free to craft the response however you like so in addition to knowing if there was a failure your application could also immediately know why.

You already basically wrote the PHP/HTML that does inserts when you wrote your update script. The insert script would be nearly the same except no ID would be provided and the SQL statement would lose the WHERE clause and change from an UPDATE to an INSERT. Very similar though… infact you may want to just build an HTML insert form just to confirm it’s adding records properly and then alter your application to send POST requests to it.

So instead of appending to a csv your application would send a POST request to your insert script which would insert the record into the database (or not) then just return a 1 for success or 0 for fail… or whatever data you’d like your application to have.

I think getting rid of the intermediate csv files is just the last step towards the elegant setup you had originally envisioned. Nice job getting it working to this point btw. I didn’t think you’d manage to pull it off when I first checked in on this thread. If you want to leave it as is I fully understand because “if it ain’t broke…” or you could check out the link below.

1 Like

.CSV does a couple of things for us actually. We like to pre-format the data before it goes in the database. For example, instead of Intel(R) Core i5 8365U @ 1.60GHz we read that raw value, compare it against a list of known values, and replace it with CORE i5 8365U 1.60. Same with GPUs, same with System Product Names, even the Part Number goes through error correcting. Those FZ-55’s. FZ-55C9-00VM cannot be read from anywhere and there’s a FZ-55C1-00VM version but there is a raw data value associated with both so we can replace them for what we want in the database.

Basically. The .CSV lets me check for data errors in bulk and add new hardware to the known hardware comparison lists before they go into the database so it’s not a bad intermediary.

Also these are used computers which means they come in every physical condition ranging from near spotless to completely trashed. If I plug in 36 computers and let them image there’s always one or two in every round that misbehave and because they all turn off after imaging I have to go find the one or two that never even made it to Windows or WinPE for that matter.

With the .CSV file and Notepad++ I can live monitor each round of 36 and identify how many and sometimes what model didn’t make it to Windows during deployment. I would have to completely overhaul the front-end for MySQL if I wanted to live monitor the computers as they went in which sounds like a beast of scripting I am not prepared for.

I also keep a backup of all the .CSV files so if there’s a failure of the SQL server we still have a independently maintained backup record we can recover from.

With the .CSV I can also pass the files off to myself and my co-worker to import the hardware details to the live company database. I don’t know what the back-end is they use but the front end is Microsoft Access and the company owner said he wants a MySQL database so it’s not using that. Maybe Access hosts it’s own back-end.

…Though the idea to go from C# strait to HTTP/PHP/SQL sounds like the more proper way to go about it this independent database is more archival and we benifit too much from maintaining the .CSV system. It just wasn’t ideal for doing lookup queries. SQL and a handful of HTTP/PHP gives me a great way of looking up past records now. I’m more concerned about making sure my SQL columns are configured appropriately for the data they’re storing and what feature improvements I can add to HTML/PHP to make the front-end more dynamic and informative when I need it.

For example <?php include "templates/footer.php"; ?> This file is literally just </body></html> it would be cool if I could add a table that sits at the foot of each page and just tells me info about the database like how many records exist, maybe when it was last updated, any other information I’d like to view at any given moment.

I think I’m going to go ahead and build a mock-copy of this database at home and spend some time playing with HTML & PHP which I haven’t done in years. This way I can experiment with adding features to my hearts content and just copy/paste my changes to the live server at work when I’ve fiured out how to make something new work.

If there is one thing I am no less it is a stubborn *astard. :laughing: I will trial/error and ask for help until I achieve an objective if I want it bad enough. Don’t get me started on how complicated the code is in the program that makes the .CSV file. :rofl:

But to credit I owe my college this knowledge. They made me take a class about 6 years ago that was very specifically HTTP + PHP + MySQL and the whole course only taught Creation/Read/Update/Delete.

While trying to refresh my knowledge on the topic I read some info that this method is starting to or has depreciated for alternative more modern methods but I’m sticking to what I know and building off of that.

Even though I will probably opt to stay with .CSV I still like the idea of learning this POST thing because if I get C# and I get HTML/PHP/SQL then I might find a use elsewhere on how to do that when .CSV really isn’t benefiting. Maybe I will have individual times where I want C# to just port the data strait to the database instead of waiting for cron like you said.