Data retrieval from database using perl with a foreach - sql

$dbh_source2 = DBI->connect("dbi:Oracle:host=.......;port=......;sid=......",'..........','..........');
foreach $data_line (#raw_data) {
$SEL = "SELECT arg1,arg2 FROM TABLE_NAME WHERE DATA_NAME = '$data_line'";
$sth = $dbh_source2->prepare($SEL);
$sth->execute();
while (my #row = $sth->fetchrow_array() ) {
print #row;
print "\n";
}
}
END {
$dbh_source2->disconnect if defined($dbh_source2);
}
I am trying to grab several lines of data from a user. I want to take that data and use it to query a database and grab ARG1 and ARG2 WHERE USER_DATA = $data_line.
It will not display anything.

Here's a quick revision which uses SQL placeholders in order to keep Bobby Tables from destroying your database. It may also fix the problem you're currently having, but I haven't seen enough details of your problem yet to be sure.
my $dbh_source2 = DBI->connect("dbi:Oracle:host=.......;port=......;sid=......",'..........','..........');
my $SEL = "SELECT arg1,arg2 FROM TABLE_NAME WHERE DATA_NAME = ?";
my $sth = $dbh_source2->prepare($SEL);
foreach my $data_line (#raw_data) {
$sth->execute($data_line);
while (my #row = $sth->fetchrow_array() ) {
print #row;
print "\n";
}
}
END {
$dbh_source2->disconnect if defined($dbh_source2);
}

my $dbh_source2 = DBI->connect
("dbi:Oracle:host=.......;port=......;sid=......",'..........','..........');
my $SEL = "SELECT arg1,arg2 FROM TABLE_NAME WHERE DATA_NAME = ?";
my $sth = $dbh_source2->prepare($SEL);
foreach my $data_line (#raw_data) {
chomp $data_line;
$sth->execute($data_line);
while (my #row = $sth->fetchrow_array() ) {
print "$data_line\t #row\n";
}
}
END {
$dbh_source2->disconnect if defined($dbh_source2);
}
The issue I was having was the fact that the development database was not updated with the correct information so some of the items came up blank. When using the production database with the correct information it worked great!
Thank you all for your help!

Related

Empty response when making a Select with 2 where clauses

My function of XMLRPC works like this, check if content already exists at my website, if it is up-to-date and update it if necessary.
To do it I check for it´s number ( both content types can have same number) it´s hash (unique) and type.
Before I had only one kind of content, and my function was working properly , but now I need to check also content type instead of only number and hash.
that is the problem, whem I try to do it, I got an empty anwser. My Function now is like this:
$query = db_query("SELECT (table_num.field_num) FROM (table_num, table_type) WHERE table_num.entity = table_type.entity AND table_num.field_num = :num AND table_type.field_type = :type", array(':num' => $num, ':type' =>$type));
foreach ($query as $record) {
if($record->rowCount()==0) return 0;
else {
$query = db_query("SELECT (table_hash.field_hash) FROM (table_hash, table_type) WHERE table_hash.entity = table_type.entity AND table_hash.field_hash = :hash AND table_type.field_type = :type", array(':hash' => $hash, ':type' =>$type));
foreach ($query as $record) {
if($record->rowCount()==1) return 1;
else{
$query = db_query("SELECT (table_num.entity_id) FROM (table_num, table_type) WHERE table_num.entity = table_type.entity AND table_num.field_num = :num AND table_type.field_type = :type", array(':num' => $num, ':type' =>$type));
foreach ($query as $record) {
echo $record->field_entity_id;
}
return $record;
P.S. when it returns 0 it does not exists in my DB, 1 is when it´s up to date and entity when I need to update it.
Sorry for long SQL but I just start to use it, and I didn´t manage to get it shorter.
Does someone have any idea why I am getting an empty anwser?
The way your building your queries is dangerous and lead to SQL injection as your not escaping your variables.
Instead of:
$query = db_query("SELECT (table_num.field_num) FROM table_num WHERE table_num.field_num = $num AND table_type.field_type = $type");
You can use:
$query = db_query("SELECT (table_num.field_num) FROM table_num WHERE table_num.field_num = :num AND table_type.field_type = :type", array(':num' => $num, ':type' =>$type));
This way Drupal will sanitize your variables before inserting them so you know it won't lead to any vulnerabilities.
I don't actually fully understand what your question is asking - if you could clarify it a bit I'll see if I can help with that too...

Nested while loop needed?

I've got this code working but it's only pulling out the first neighbourhood group that matches one of the values from the 1st query. The code is in a Node ID PHP handler in a view in Drupal.
The first query puts all of the postal codes from the government's jurisdiction into an array. The second query reads through all of the neighbourhood groups to find all those that match those in that array.
It looks like I need a second loop or something since the while that's there now isn't getting every neighbourhood groups that match any of the values in the array. Can anyone see what I'm missing?
Here's the code:
$government_nid = custom_get_groupid();
$codes_list = array();
$neighbourhood_list = array();
$results = db_query("SELECT field_jurisdiction_postal_codes_value FROM {content_field_jurisdiction_postal_codes} WHERE
nid = %d", $government_nid);
while($return_list = db_fetch_array($results)){
$codes_list[] = $return_list[field_jurisdiction_postal_codes_value];
}
$results1 = db_query("SELECT nid FROM {content_type_neighbourhood_group} WHERE
field_postal_code_3_value IN ('%s')", $codes_list);
while($return_list1 = db_fetch_array($results1)){
$neighbourhood_list[] = $return_list1[nid];
}
$neighbourhood_string = implode(', ', $neighbourhood_list);
return $neighbourhood_string;
Here's the answer:
foreach ($codes_list AS $value) {
$results1 = db_query("SELECT nid FROM {content_type_neighbourhood_group} WHERE
field_postal_code_3_value = '%s'", $value);
while($return_list1 = db_fetch_array($results1)){
$neighbourhood_list[] = $return_list1[nid];
}
}
$neighbourhood_string = implode(', ', $neighbourhood_list);
return $neighbourhood_string;

SELECT issue moving from PG_query to PDO

I have a select statement see below. Using PDO how would I recreate this same Select statement, as I want to grab two values from it and combine them into the $geomstring. I can figure out the combine, but not the first 3 lines.
$sql1 = "SELECT easting_value, northing_value FROM gridreference_tbl WHERE gridref_id='$_POST[gridref_id]'";
$result1 = pg_query($sql1);
$row1 = pg_fetch_array($result1);
$geomstring = $row1['easting_value']. $_POST['grid_eastings']." ".$row1['northing_value'].$_POST['grid_northings'];
*php website for prepared statements says *
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
if ($stmt->execute(array($_GET['name']))) {
while ($row = $stmt->fetch()) {
print_r($row);
}
}
I have something similar working for populating a dropdown that partly uses this
$stmt = $conn->prepare("SELECT easting_value, northing_value FROM gridreference_tbl WHERE gridref_id=$gridref_id");
$stmt->setFetchMode(PDO::FETCH_OBJ);
Found it on php.net, I was googling the wrong stuff:
$stmt4 = $conn->prepare("SELECT easting_value, northing_value from gridreference_tbl WHERE gridref_id = 4");
$stmt4->execute();
print("PDO::FETCH_ASSOC: ");
print("Return next row as an array indexed by column name\n");
$result = $stmt4->fetch(PDO::FETCH_ASSOC);
print_r($result);
print("\n");

my query take a long time to run ,why?

I have a query that returns c.a 1800 records( not many) but It takes long time to ran (10 seconds) but I can not understand why?
this is my query that takes a long time:
SELECT tb_KonzeptFunktionen.Konzept AS KonzeptID, tb_KonzeptFunktionen.Funktion,
tb_KonzeptFunktionen.Version,
qryFunktionen_Übersicht.ID,
qryFunktionen_Übersicht.Fehlerpfad_Kommentar AS Kommentar,
qryFunktionen_Übersicht.Fehlerpfadname,
qryFunktionen_Übersicht.Fehlerpfad_CDT,
qryFunktionen_Übersicht.Fehlerpfad_Kommentar,
qryFunktionen_Übersicht.symptombasiert,
qryFunktionen_Übersicht.Beschreibung_vorhanden,
qryFunktionen_Übersicht.Max_Pfad,
qryFunktionen_Übersicht.Max_Info,
qryFunktionen_Übersicht.Max_Status,
qryFunktionen_Übersicht.Max_Strategie,
qryFunktionen_Übersicht.Max_Prüfplan,
qryFunktionen_Übersicht.Min_Pfad,
qryFunktionen_Übersicht.Min_Info,
qryFunktionen_Übersicht.Min_Status,
qryFunktionen_Übersicht.Min_Strategie,
qryFunktionen_Übersicht.Min_Prüfplan,
qryFunktionen_Übersicht.Sig_Pfad,
qryFunktionen_Übersicht.Sig_Info,
qryFunktionen_Übersicht.Sig_Status,
qryFunktionen_Übersicht.Sig_Strategie,
qryFunktionen_Übersicht.Sig_Prüfplan,
qryFunktionen_Übersicht.Plaus_Pfad,
qryFunktionen_Übersicht.Plaus_Info,
qryFunktionen_Übersicht.Plaus_Status,
qryFunktionen_Übersicht.Plaus_Strategie,
qryFunktionen_Übersicht.Plaus_Prüfplan,
qryFunktionen_Übersicht.Beschreibung_allgemein,
qryFunktionen_Übersicht.Funktionsname
FROM tb_KonzeptFunktionen RIGHT JOIN qryFunktionen_Übersicht
ON tb_KonzeptFunktionen.Funktion = qryFunktionen_Übersicht.Funktionsname
WHERE (((tb_KonzeptFunktionen.Konzept)=[Formulare]![frm_Fahrzeug]![ID]))
and this is another related query to above query:
SELECT tbFunktionen_Übersicht.*,
tbFunktionen.Funktionsname,
tbFunktionen.Funktionsbeschreibung,
tbFunktionen.diagnoserelevant,
tbFunktionen.ID AS FunktionsID
FROM tbFunktionen_Übersicht INNER JOIN tbFunktionen
ON tbFunktionen_Übersicht.Funktion = tbFunktionen.ID
ORDER BY tbFunktionen.Funktionsname, tbFunktionen_Übersicht.Fehlerpfadname;
I added an index to the fields that appear in ORDER oder JOINS but no effect
Would you please help me if possible?
Please refer to this post,hier you can find the answer
for me PDO brought improvement in my sql query's: http://www.php.net/manual/en/intro.pdo.php
//SQL-HANDLING*******************************************************//
//*********************************************************************//
//General Example-----------------
//$sqlHandling = new sqlHandling;
//$sqlHandling->connectSQL($sqlArray['host'], $sqlArray['user'],$sqlArray['pass'], $sqlArray['dbName']);
//$tableNameArray = $sqlHandling->showTablesSQL($sqlHandling->dbh);
class sqlHandling{
//PDO - Object/ callItOutside with: $sqlClass->dbh
public $dbh = null;
//connectDataBase-------------------//
//-----------------
//example: $dbh = connectSQL('localhost','admin','1admin','test');
//start transaction
//$dbh->beginTransaction();
//-----------------
//end transaction
//$dbh->commit();
//$dbh = null;
//-----------------
//1:SQL-Location
function connectSQL($host, $user, $pass, $dbname){
//endPrevTransaction
if($this->dbh != null){
$this->dbh->commit();
$this->dbh = null;
}
//establish connection
try{
$this->dbh = new PDO('mysql:host='.$host.';dbname='.$dbname, $user, $pass);
$this->dbh->exec('SET CHARACTER SET utf8');
return $this->dbh;
}catch(PDOException $e){
print 'Error!: ' . $e->getMessage() . '<br/>';
die();
return FALSE;
}
}
//createColumnSQL-------------------//
//example: createColumnSQL($dbh, 'backupexample', array('SomeName1 VARCHAR(30)', 'SomeName2 VARCHAR(30)', 'SomeName3 VARCHAR(30)', 'SomeName4 VARCHAR(30)'));
//1:PDO connection/2:table/3:array holding columns
function createColumnSQL($dbh, $table, $columns){
//cicle through each array
foreach($columns as $tempColumn){
//set query
$query = 'ALTER TABLE `'.$table.'` ADD COLUMN '.$tempColumn;
//send the query
$stmt = $dbh->prepare($query);
//send the data
$stmt->execute();
}
}
}
This is only a working example for my PDO sqlHandling Class. I know retrieveAllValues won't help you further but you may adopt this code for your use.
MFG

How can I UPDATE rows returned by a SELECT in a loop?

I have a loop on the rows returned by an SQL SELECT statement, and, after some processing on a row's data, I sometimes want to UPDATE the row's value. The processing in the loop's body is non-trivial, and I can't write it in SQL. When I try to execute the UPDATE for the selected row I get an error (under Perl's DBD::SQLite::st execute failed: database table is locked). Is there a readable, efficient, and portable way to achieve what I'm trying to do? Failing that, is there a DBD or SQLite-specific way to do it?
Obviously, I can push the updates in separate data structure and execute them after the loop, but I'd hate the code's look after that.
If you're interested, here is the corresponding Perl code.
my $q = $dbh->prepare(q{
SELECT id, confLoc FROM Confs WHERE confLocId ISNULL});
$q->execute or die;
my $u = $dbh->prepare(q{
UPDATE Confs SET confLocId = ? WHERE id = ?});
while (my $r = $q->fetchrow_hashref) {
next unless ($r->{confLoc} =~ m/something-hairy/);
next unless ($locId = unique_name_state($1, $2));
$u->execute($locId, $r->{id}) or die;
}
Temporarily enable AutoCommit:
sqlite> .header on
sqlite> select * from test;
field
one
two
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
my $dbh = DBI->connect('dbi:SQLite:test.db', undef, undef,
{ RaiseError => 1, AutoCommit => 0}
);
test_select_with_update($dbh);
sub test_select_with_update {
my ($dbh) = #_;
local $dbh->{AutoCommit} = 1;
my $q = $dbh->prepare(q{SELECT field FROM test});
my $u = $dbh->prepare(q{UPDATE test SET field = ? WHERE field = ?});
$q->execute or die;
while ( my $r = $q->fetchrow_hashref ) {
if ( (my $f = $r->{field}) eq 'one') {
$u->execute('1', $f) or die;
}
}
}
After the code has been run:
sqlite> .header on
sqlite> select * from test;
field
1
two
Your problem is that you're using the same database handler to perform an update while you're in a fetching loop.
So have another instance of your database handler to perform the updates:
my $dbh = DBI->connect(...);
my $dbhForUpdate = DBI->connect(...) ;
Then use dbhForUpdate in your loop:
while(my $row = $sth->fetch()){
...
$dbhForUpdate->do(...) ;
}
Anyway, I wouldn't recommend doing this since there's good chances you run into concurrency issues at the database level.
More in answer to Zoidberg's comment but if your were able to switch to an ORM like Perl's DBIx::Class then you find that you could write something like this:
my $rs = $schema->resultset('Confs')->search({ confLocId => undef });
while ( my $data = $rs->next ) {
next unless $data->confLoc =~ m/(something)-(hairy)/;
if ( my $locId = unique_name_state( $1, $2 ) ) {
$data->update({ confLocID => $locid });
}
}
And if DBIx::Class doesn't grab your fancy there are a few others on CPAN like Fey::ORM and Rose::DB for example.