SQL select statement with AND and OR operators issue - sql

I'm fetching records from the SQL Server 2000 database using Classic ASP. This is what the code I have used.
ASP Code:
<form name="search" method="post" onsubmit="return attention();">
<table width="60%" border="0" cellpadding="2" cellspacing="0" style="margin:0 auto">
<tr>
<td colspan="2"><h1 style="color:#003399;">Search for Certificate of Analysis</h1></td>
</tr>
<tr>
<td valign="bottom">Product number <sup style="color:#EE0000;font-size:1.3em">*</sup></td>
<td valign="bottom">Lot number</td>
</tr>
<tr>
<td width="30%" valign="top">
<input type="text" name="input1" size="20"/>
</td>
<td valign="top">
<input type="text" size="20" name="input2"/>
<input style="background-color:#ffffff;border:0px;cursor:pointer" size="10" type="submit" name="sub" value=">>" />
</td>
</tr>
</table>
<%
if request.Form("sub") <> "" then
Dim fname, lname
fname= request.Form("input1")
lname= request.Form("input2")
session("n") = fname & lname
sql = "Select * from search where cat_no_batch_no LIKE '"&request.Form("input1")&"%' OR cat_no_batch_no='"&session("n")&"'"
rs.open sql, con, 1, 2
if rs.eof then
response.write("Please provide a valid Cat No.")
else
do while not rs.eof
%>
<table border="1" cellpadding="5" cellspacing="0" width="60%" style="margin:0 auto; border-collapse:collapse;border-color:#999999">
<tr>
<td width="50%"><%=rs("cat_no_batch_no")%></td>
<td width="10%">Click to open <a target="_blank" href="http://localhost/search1/<%=rs("pdf_path")%>"><%=rs("cat_no_batch_no")%></a></td>
</tr>
</table>
<%
rs.movenext
loop
end if
rs.close
end if
%>
</form>
Above the LIKE statement works as expected and displays multiple records which contains similar Cat No..
Issue rises when I input a Cat No in first Input box and Lot Number in another. My desired output should have been just a single record to display as I have given Cat No. and Lot Number , but it shows multiple records.
I have provided the images to be more clear.
In this image below I have put 6106021 as the product number so it displays two entries.
In this image I have put 6106021 as the product number and 218111 as the Lot Number, it shows two entries instead of 1. This is what the issue, it should show one entry as Lot number are unique while cat number can be the same.

Read your question to yourself and think about what you are saying:
You state "My desired output should have been just a single record to display as I have given Cat No. and Lot Number"
But in your SQL you write where cat_no_batch_no LIKE '"&request.Form("input1")&"%' OR cat_no_batch_no='"&session("n")&"'
The key words are AND vs. OR
In your mind you are thinking both conditions must be true, but your query says otherwise. If you want both conditions to be true then you must use the AND operator.
Naoki is on to something - you are going to have to modify your SQL depending upon which criteria are specified.

I guess you can write two separate SQL queries, according as the "Lot number" is provided or not.
Your code may goes like below:
if lname = "" then
sql = "Select * from search where cat_no_batch_no LIKE '"&request.Form("input1")&"%'"
else
sql = "Select * from search where cat_no_batch_no LIKE '"&session("n")&"%'"
end if
I hope this could help

Related

WebBrowser - Get/Read data from generic Tables with no ID, no TagName, no Class

As title, I'm trying to read data from some tables in a page.
I often use WebBrowser1.Document.GetElementById for lot of similar things, but in this case I'm unable to access data, since in this page all tables are simply defined by <table class="table">
Here is what I'm trying to access :
<div class="col-md-6">
<div class="panel panel-primary">
<!-- Default panel contents -->
<div class="panel-heading">
<h3 class="panel-title">Ryzen 3000 - Mainstream</h3>
</div>
<!-- Table -->
<table class="table">
<tbody>
<tr>
<th>Ryzen 5 3500</th>
<td>3.6 - 4.1</td>
</tr>
<tr>
<th>Ryzen 5 3500X</th>
<td>3.6 - 4.1</td>
</tr>
<tr>
<th>Ryzen 5 3600</th>
<td>3.6 - 4.2</td>
</tr>
<tr>
<th>Ryzen 5 Pro 3600</th>
<td>3.6 - 4.2</td>
</tr>
<tr>
<th>Ryzen 5 3600X</th>
<td>3.8 - 4.4</td>
</tr>
<tr>
<th>Ryzen 5 3600XT</th>
<td>3.8 - 4.5</td>
</tr>
</tbody>
</table>
</div>
<!--</panel>-->
</div>
I searched a lot on the web, but I was unable to found a valid solution.
Does anyone have hints?
I recommend you to use HtmlAgilityPack and Xpath analytical formula.
Sample code:
Query specific th label text:
Dim doc As HtmlAgilityPack.HtmlDocument
Dim path As String = "https://www..."
Dim web As New HtmlWeb
doc = web.Load(path)
Dim node As HtmlAgilityPack.HtmlNode
'The text within the fourth <th></th>
node = doc.DocumentNode.SelectNodes("//table[#class='table']//th")(3)
Dim st As String = node.InnerText 'Ryzen 5 Pro 3600
Query all tr text:
Dim doc As HtmlAgilityPack.HtmlDocument
Dim path As String = "https://www..."
Dim web As New HtmlWeb
doc = web.Load(path)
Dim nodes As HtmlAgilityPack.HtmlNodeCollection
nodes = doc.DocumentNode.SelectNodes("//table[#class='table']//tr")
For Each node As HtmlNode In nodes
RichTextBox1.AppendText(node.InnerText)
Next
Result:

grabTextFrom finds anticipated string that assertion using Locator::contains cannot

I have an interesting case with the following HTML and a Codeception Acceptance test using PhpBrowser, which I've not been able to find a similar issue for on StackOverflow.
I am looking to assert that the content of a P tag (as part of the only table on the page) contains an anticipated phrase.
// representative code
$anticipatedValue = "updated text description";
$xpath = "//table/tbody/tr[position() = 1]/td[position() = 2]/descendant::p";
$val = $I->grabTextFrom($xpath); // this equals the value of $anticipatedValue;
echo "the value is[" .$val."][".$anticipatedValue."]"; // these match perfectly, no trimming needed
$I->see(Locator::contains($xpath,$anticipatedValue)); //this fails
$I->see(Locator::contains($xpath,$val)); //so does this
The fail HTML output does not display anything out of the ordinary. I am hoping someone with more experience of XPath in PhpBrowser can point out what I am missing.
The HTML portion I am looking at is below. This is a legacy application I am adding tests to, so the HTML is at present, as you can see, not optimal.
<table id="calendar" class="unitable" cellspacing=0 cellpadding=0>
<thead>
<tr>
<th>Time</th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="past"><td>10 Dec 00:00</td>
<td class="entry" rowspan=2>
<div class="time">Tue 10 09:00 - Tue 10 17:00</div>
<div class="stage">new stage B</div>
<p class="description">updated text description</p>
</td>
</tr>
<tr class="past">
<td>10 Dec 12:00</td>
</tr>
<tr class="past">
<td>11 Dec 00:00</td>
<td class="entry" rowspan=1>
<div class="time">Wed 11 09:00 - Wed 11 11:30</div>
<div class="stage">new stage C</div>
<p class="description">this is new stage C</p>
</td>
</tr>
<tr class="past">
<td>11 Dec 12:00</td>
<td></td>
</tr>
<tr class="past">
<td>12 Dec 00:00</td>
<td></td>
</tr>
<tr class="past">
<td>12 Dec 12:00</td>
<td class="entry" rowspan=1>
<div class="time">Thu 12 13:30 - Thu 12 17:00</div>
<div class="stage">new stage D</div>
<p class="description">this is new stage D</p>
</td>
</tr>
</tbody>
<tfoot></tfoot>
</table>
and the failure report reads:
Failed asserting that on page ...
{short snippet of upper page HTML - not from the area under scrutiny, followed by}
[Content too long to display. See complete response in '/var/www/public/vhosts/system/tests/_output/' directory]
--> contains "//table/tbody/tr[position() = 1]/td[position() = 2]/descendant::p[contains(., 'updated text description')]".
Many thanks for your consideration of this issue.
Your problem is that you pass result of Locator::contains to $I->see() method,
see expects to get a string as a first parameter and it is looking for that exact text in HTML.
Start with
$I->see('updated text description');
If you want to check if the text is displayed in specific location, pass XPath expression as a second parameter:
$I->see('updated text description', '//table/tbody/tr[position() = 1]/td[position() = 2]/descendant::p');
as documented at https://codeception.com/docs/modules/PhpBrowser#see

How to create table for my perl output using perl cgi?

Here is my code and output i was unable to create the different row for my each line using perl?
Here is my code:
use strict;
use warnings;
use CGI;
open(my $file1,"as.txt");
my $firstline=<$file1>;
$firstline=~s/.*=//g;
my #words=split /,/,$firstline;
my $finalline=join("\n",#words);
close $file1;
print "Content-type:text/html\n\n"
print<<"EOF";
<html><body>
<table style="width:100%">
<tr>
<th>UserName</th>
<th>Access</th>
</tr>
<tr>
<td>$finalline</td>
<td>
<input type="checkbox" value="check2" mulitple checked>Read
<input type="checkbox" value="check2" mulitple>Write
<input type="checkbox" value="check2" mulitple>Owner
</td>
</tr>
</table></body></html>
EOF
MY OUTPUT FOR PERL (I.E $finalline)
sankar
morien3
i got the following table as my output in table format:
UserName Access
sankar morien3 Read Write Owner
Expected output:
UserName Access
sankar Read Write Owner
morien3 Read Write Owner
Input file:(i.e as.txt)
cskTeam = sankar, mobrien3
[csk:/]
* = r
#cskTeam = rw
You must know about how HTML layout will work.
Even your code won't give your expected result in terminal.
In html \n not make sense, <br> it is for new line in html. But this logic also won't work in your code.
You are joining the array with \n, then printing the data it will execute the comment line by line what you have mentioned.
First you have printing the $finalline variable so it result is
sankar \n morien3
\n will not consider in html. Storing in one cell as per <td>
Then you are creating the another cell which holds the permission detail.
Finally your code should be as follows.
#!/usr/bin/perl
use warnings;
use strict;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
print "Content-Type: text/html \n\n";
open my $file1,"<","as.txt";
my $firstline=<$file1>;
$firstline=~s/.*=//g;
my #words=split /,/,$firstline;
close $file1;
print<<"EOF";
<html><body>
<table style="width:50%; ">
<tr>
<th style="text-align:left">UserName</th>
<th style="text-align:left">Access</th>
</tr>
EOF
foreach (#words)
{
print <<EOF;
<tr>
<td>$_</td>
<td>
<input type="checkbox" value="check2" mulitple checked>Read
<input type="checkbox" value="check2" mulitple>Write
<input type="checkbox" value="check2" mulitple>Owner
</td>
</tr>
EOF
}
print <<EOF;
</table></body></html>
EOF

How do I display SUM(Quantity) while using GROUP BY command in HTML

I am able to display the ItemID perfectly fine and the ItemIDs group together. When I try the SQL statement in MS Access the quantities add up perfectly fine but I can't manage to replicate this in HTML.
This is the code
<%
dim Con,rs, sql
set con = server.CreateObject("ADODB.Connection")
set rs = server.CreateObject("ADODB.Recordset")
Con.Open("DRIVER={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ=" & Server.MapPath("Database/Name.accdb"))
sql = "SELECT ItemID, SUM(Quantity) FROM tblCreatedItems GROUP BY ItemID ORDER BY tblCreatedItems.ItemID"
rs.open sql, Con
%>
<body>
<table width="467" align="center">
<th colspan="5"><strong>Items Sold</strong></th>
<tr>
<td width="119"><strong>ItemID</strong></td>
<td width="165"><strong>Quantity</strong></td>
</tr>
<tr>
<% while not rs.eof%>
<td><%=rs("ItemID")%></td>
<td>
<% dim sql2
set sql2=con.execute("SELECT SUM(Quantity) FROM tblCreatedItems GROUP BY ItemID ORDER BY tblCreatedItems.ItemID" )
response.Write(sql2)
%></td>
</tr>
<% rs.movenext
wend
%>
</table>
</body>
You are already grouping by the itemid in the first query, and don't need a second query to show the sum.
In your sql add an alias (a name to reference the field) to the SUM field:
change SUM(Quantity) to SUM(Quantity) as NoOfItems (or whatever you like, as an alias)
The sql statement becomes:
SELECT ItemID, SUM(Quantity) as NoOfItems
FROM tblCreatedItems
GROUP BY ItemID
ORDER BY tblCreatedItems.ItemID
And Then:
<td><%=rs("NoOfItems")%></td>
should show your sum field.
So, your table code becomes:
<table width="467" align="center">
<th colspan="5"><strong>Items Sold</strong></th>
<tr>
<td width="119"><strong>ItemID</strong></td>
<td width="165"><strong>Quantity</strong></td>
</tr>
<tr>
<% while not rs.eof%>
<td><%=rs("ItemID")%></td>
<td><%=rs("NoOfItems")%></td>
</tr>
<% rs.movenext
wend
%>
</table>

SQL Join in CodeIgniter

I have one file, then for every file there are multiple comments about that file. I was able to successfully join the two tables, comments and files, however when I try to view the page where it displays the file and its comments, the page displays the name of file n times (n corresponds to the number of records of comments of that certain file).
How will I be able to display just once the file name as well as displaying the comments?
<table width="40%" align="center">
<?php foreach($rows as $file):?>
<tr>
<td width="70%" id="title"><?php echo $file->name; ?></td>
</tr>
<?php endforeach;?>
</table>
<table width="40%" align="center" frame="above" style="margin-top:10px; border-top-width:3px; border-top-color:#666666">
<?php foreach($rows as $file):?>
<tr>
<td width="15%"></td>
<td width="45%" id="name">FILESIZE:</td>
<td width="40%" id="txt3"><?php echo $file->size; ?></td>
</tr>
<tr>
<td></td>
<td id="name">DATE UPLOADED:</td>
<td id="txt3"><?php echo $file->dateUploaded;?></td>
</tr>
<?php endforeach;?>
</table>
<!--COMMENTS -->
<table align="center" frame="above" style="margin-top:10px; border-top-width:3px; border-top-color:#666666" width="40%">
<tr>
<td><h3>Comments</h3></td>
</tr>
<tr><?php foreach($rows as $comment):?>
<td><?php echo $comment->comm;?></td>
</tr><?php endforeach;?>
</table>
You can use
GROUP_CONCAT()
in your join.
SELECT person.id AS id, name, GROUP_CONCAT(role.role SEPARATOR ',') AS roles
FROM person
LEFT OUTER JOIN person_role ON person.id=person_role.person_id
LEFT OUTER JOIN role ON person_role.role_id=role.id
GROUP BY id
ORDER BY id;
is an example from a tutorial at
http://dev-loki.blogspot.com/2008/01/aggregate-join-results-with-mysql-using.html
can't give much better without seeing your schema.
EDIT: trying anyway.
SELECT files.*, GROUP_CONCAT(comments.comment SEPARATOR ',') as comments_list
FROM files
LEFT JOIN comments on files.id = comments.id
GROUP BY id
ORDER BY id
Adding onto orbit, in codeigniter if your using activerecord it would be:
(Sorry, I couldn't format code in a comment)
$this->db->select('person.id AS id, name, GROUP_CONCAT(role.role SEPARATOR ',') AS roles',false);
$this->db->from('person');
$this->db->join('person_role', 'person.id = person_role.person_id', 'left outer');
$this->db->join('role', 'person_role.role_id = role.id', 'left outer');
$this->db->group_by('id');
$this->db->order_by('id'):
$this->db->get();
well it looks like you're echoing the filename for each row that is returned
your rows are getting returned like
name | size | comment1
name | size | comment2
so just don't do foreach ($rows as $file) that will print out the filename each time, just change
<?php foreach($rows as $file):?>
<tr>
<td width="70%" id="title"><?php echo $file->name; ?></td>
</tr>
<?php endforeach;?>
to
<tr>
<td width="70%" id="title"><?php echo $rows[0]->name; ?></td>
</tr>