Order by properly on SNMP oids - php

I've searched and tried lots of things but I can't find a solution.
I am storing some SNMP OIDs in a database, and displaying them in a table with datatables.
I want the OIDs to be displayed in the correct order so for example:
1.3.6.1.2.1.1
1.3.6.1.2.1.10
1.3.6.1.2.1.2
In correct order would be:
1.3.6.1.2.1.1
1.3.6.1.2.1.2
1.3.6.1.2.1.10
A SQL query with order by on the column storing the OID string would order them:
1.3.6.1.2.1.1
1.3.6.1.2.1.10
1.3.6.1.2.1.2
I'm using serverside processing with either PHP or preferably python flask. Currently I am building the table myself in flask and have written a function that orders them by converting the OIDs to tuples and sorting. This works but I would like to use datatables to get the pagination and responsiveness.
One thing to note is there isn't a limit on the length of the OID.
Any ideas would be much appreciated.

This is kind of a hack, but it might work. If each element in the OID has a max value < 100, then create a second column in the database, where each element is converted to a 2-digit 0-filled value:
real_oid sorting_oid
1.3.6.1.2.1.1 01.03.06.01.02.01.01
1.3.6.1.2.1.10 01.03.06.01.02.01.10
1.3.6.1.2.1.2 01.03.06.01.02.01.02
You could even eliminate the periods to save space, once you tested that is is all working.

First split the string on the period and typecast to int. Then use sorted and operator.itemgetter to sort by multiple attributes. Then re-join using a period. Something like the following:
original_oids = [...]
split_and_typecast_oids = [map(int, oid.split(".")) for oid in original_oids]
sorted_oids = sorted(split_and_typecast_oids, operator.itemgetter(1,2,3,4,5,6,7))
rejoined_oids = [".".join(map(str, oid)) for oid in sorted_oids]

Related

how to use php method like "explode" in sql

I am trying to get some data, and in the table, there is a field named "sysload". However, it is a var(string) type. The data in it is like "0.0, 0.2, 0.5",three numbers split by comma. However, in the sql, I only need the last number(in this example:0.5) to compare in "where". So how can I use it ? My code:
$termquery=mysql_query("SELECT a.terminal FROM terminal_server_log a
inner join
(
SELECT terminal, MAX(timestamp) timestamp
FROM terminal_server_log
group by terminal
) b on (b.terminal=a.terminal and a.timestamp=b.timestamp)
WHERE explode(',', sysload)[2]>$number");
The last line is the most important one, i want to compare with '$number', but it seems i cannot use 'explode'. Thanks
You can probably use regular expressions to match the last element of your sysload column: https://dev.mysql.com/doc/refman/8.0/en/regexp.html#function_regexp-instr
Look also at CAST() function, as the extracted substring should be converted to a numeric value to allow comparison with a number.
PHP functions will not work inside SQL queries.
You can remove this filter from your query and filter at the php side, or you can make a custom explode function using some mysql string functions.
In this link has an example: (I didn't check if it's working)
Equivalent of explode() to work with strings in MySQL

Search value of a field using substring

I'm working on a project using the pages in php / mysql and html; I have a table that contains the data for calls made from a PBX and save the number called, the source, date, time, etc ... what I want to do is to search within this table all the phone numbers that have the first 4 digits equal to those that pass through the query, only that i have no idea how to pull off only the 4-digit or at least how to make a control character by character of the value contained in the field. I tell you now that the field is a varchar. Thank you in advance :)
To do that in MySQL query, either
SELECT *
FROM <tablename>
WHERE LEFT(<column>, 4) = "<4 digits>"
or
SELECT *
FROM <tablename>
WHERE <column> LIKE "<4 digits>%"
or in the PHP side :
if (strpos($column,'<4 digit>') !== false) {
echo 'true';
}
Use this, to get substring
SELECT aut_name,
RIGHT(aut_name,7)
FROM author
WHERE country='UK';
See more at: http://www.w3resource.com/mysql/string-functions/mysql-right-function.php#sthash.xKNwZeki.dpuf
I suggest this solution:
$variableWhereYoustoreTheFourDigits="1234"; //Use whatever you have in your code to set the value.
$result =$mysqli->query("SELECT number FROM yourtable where number LIKE \"$variableWhereYoustoreTheFourDigits%\");

Random string gets repeated?

I have a service on the internet where people post pictures and a short string is generated. Only one can be used ever. However, I am getting into duplicates in the database and I am seeing major problems.
Here's what I am using:
$id=rand(10000,99999);
$short_string = base_convert($id,20,36);
What would be the best way to fix it? Check from the database and keep looping till it doesn't match one? What if every possible solution and it goes in an infinite loop?
Increment the last value by a random amount instead of using a random value. Like so:
$results = mysql_query("SELECT * FROM thetable ORDER BY theId DESC LIMIT 1");
$keyToUse = 1;
if($row = mysql_fetch_array($results)) {
$keyToUse = (int)$row['theId'] + rand(1, 100);
}
Then convert the integer key to and from any format, say using base_convert.
Put your PK through an algorithm that generates a unique number from it and put that through your function.
The best bet would be to make sure the image doesn't exist by using the random number generator against the list of images before writing a new image with that number in it.
Try to increase the amount and type of characters by using an algorithm that uses numbers, letters so it increases the combinations that you can have.
Did you try using mt_rand() http://www.php.net/manual/en/function.mt-rand.php. Also you should be increasing the range.
Use md5 http://php.net/manual/en/function.md5.php
The strings produced have no conflict (with large probability).

Using Array "Keys" In a MySQL WHERE Clause

I have a data set that is generated by a Zip Code range search:
$zips:
key -> value
11967 -> 0.5
11951 -> 1.3
The key is the Zip Code (Which I need to query the Database for), and the value is the miles from the user entered zip code. I need to take the key (Zip Code) and search the database, preferably using a MySQL query similar to my current one:
$getlistings = mysql_query("SELECT * FROM stores WHERE zip IN ($zips)");
The other alternative is to change the array somehow in my code. I tried looking in code for where the array is generated originally but I couldn't find it. Any help would be greatly appreciated!! Thanks :)
You could convert the array keys to a SQL-compatible string. For example:
'11967', '11951'
and then use the string in the query.
Since the SQL query doesn't know what a php array is and there's no good way (that I know of) to extract just the keys and surround them in quotes, so this may be your best bet.
EDIT: As Ionut G. Stan wrote (and gave an example for), using the implode and array_map functions will get you there. However, I believe the solution provided will only work if your column definition is numeric. Character columns would require that elements be surrounded by apostrophes in the IN clause.
array_keys should be what you're looking for.
$zip = array_keys($zips); # gives you simple array(11967, 11951);
implode(', ', $zip); # results in: '11967, 11951'
Cannot comment the other answers, so one additional remark from my side. Depending on the country you are in and what you do with the data... In Germany there are ZIP-Codes starting with "0" so you should make sure that you either do not store them as numerical value if you want to compare them to other data (e.g. ZIP <-> geocoord-mappings) or make sure that you convert them to int everywhere and use filtering on the output.
Old ZIP codes had four numbers, new ones have five. So displaying a new ZIP with four numbers because the leading 0 is missing will lead to confusion.
Regarding use of a temporary table i would say it depends on the size of the table and how many zip codes are used in the query.
This should do it:
// array_map sanitizes the data
$zip_codes = implode(', ', array_map('intval', array_keys($zips)));
$getlistings = mysql_query("SELECT * FROM stores WHERE zip IN ($zip_codes)");
For best performance, you should create a temporary table, fill it with your ZIP codes and query like this:
SELECT *
FROM stores
JOIN temptable
ON zip = tempvalue
Of course this will be more efficient only if you ZIP column is indexed.
I just want to throw in that the previous code snippets gave me some syntax errors and the database just spitted out one entry instead of all relevant data. The following snippet worked for me:
implode("','", $zipNumbers);

mysql "with rollup" query morphed into a tree structure

Background:
I have this "with rollup" query defined in MySQL:
SELECT
case TRIM(company)
when 'apple' THEN 'AAPL'
when 'microsoft' THEN 'MSFT'
else '__xx__'
END as company
,case TRIM(division)
when 'hardware' THEN Trim(division)
when 'software' THEN Trim(division)
else '__xx__'
END as division
,concat( '$' , format(sum(trydollar),0)) as dollars
FROM pivtest
GROUP BY
company, division with rollup
And it generates this output:
AAPL;hardware;$279,296
AAPL;software;$293,620
AAPL;__xx__;$572,916
MSFT;hardware;$306,045
MSFT;software;$308,097
MSFT;__xx__;$614,142
__xx__;__xx__;$1,187,058
If you have used "with rollup" queries in MySQL before, you can most likely infer the structure of my source table.
Question:
Given this raw output of MySQL, what is the easiest way to get a "tree" structure like the following?
AAPL
hardware;$279,296
software;$293,620
Total; $572,916
MSFT
hardware;$306,045
software;$308,097
Total;$614,142
Total
$1,187,058
Easiest is to do it in whatever client program you're using to receive and show the user MySQL's output -- definitely not easiest to implement presentation-layer functionality in the data layer!-) So tell us what language &c is in your client program and we may be able to help...
Edit: giving a simple Python client-side solution at the original asker's request.
With Python's DB API, results from a DB query can be most simply seen as a list of tuples. So here's a function to format those results as required:
def formout(results):
marker = dict(__xx__=' Total')
current_stock = None
for stock, kind, cash in results:
if stock != current_stock:
print marker.get(stock, stock).strip()
current_stock = stock
if kind in marker and stock in marker:
kind = ' '*8
print ' %s;%s' % (marker.get(kind, kind), cash)
marker is a dictionary to map the special marker '__xx__' into the desired string in the output (I'm left-padding it appropriately for the "intermediate" totals, so when I print the final "grand total", I .strip() those blanks off). I also use it to check for the special case in which both of the first two columns are the marker (because in that case the second column needs to be turned into spaces instead). Feel free to ask in comments for any further clarification of Python idioms and use that may be necessary!
Here's the output I see when I call this function with the supplied data (turned into a list of 7 tuples of 3 strings each):
AAPL
hardware;$279,296
software;$293,620
Total;$572,916
MSFT
hardware;$306,045
software;$308,097
Total;$614,142
Total
;$1,187,058
The space-alignment is not identical to that I see in the question (which is a little inconsistent in terms of how many spaces are supposed to be where) but I hope it's close enough to what you want to make it easy for you to adjust this to your exact needs (as you're having to translate Python into PHP anyway, the space-adjustment should hopefully be the least of it).

Categories