Check if pg_prepare was already executed - postgresql

Is there a way to check if pg_prepare already executed and remove it from the session?
Seems like pg_close doesn't remove prepared statement from the session. Kind of seems like a bug in php, but maybe I'm missing something or maybe there is a workaround.
public static function readSubdomains($dcName, $filter = null) {
// ...
$conn = pg_pconnect($connectionString);
// ...
$result = pg_prepare($conn, "subdomains", "SELECT subdomain
from tenants
where $where
order by 1 asc
");
$result = pg_execute($conn, "subdomains", $params);
// ...
pg_close($conn);
}
Second call to readSubdomains shows a warning like this:
Warning: pg_prepare(): Query failed: ERROR: prepared expression "subdomains" already exists in inc/TestHelper.php on line 121

Always check the official manuals for this sort of stuff.
https://www.postgresql.org/docs/current/view-pg-prepared-statements.html
Oh - if pg_close isn't dropping prepared statements then it isn't closing the connection. You might have some connection pooling involved.

Related

Read timed out after reading 0 bytes, waited for 30.000000 seconds in mongodb

When I am working on above 5,000,000 records in mongodb, it shows this error "Read timed out after reading 0 bytes, waited for 30.000000 seconds" in find() query. Please any one help me.
In PHP you can set timeout(-1) to your cursor.
PHP Example:
$conn = new MongoClient("mongodb://primary:27017,secondary:27017", array("replicaSet" => "myReplSetName"));
$db = $conn->selectDB(DBname);
$collection = $db->selectCollection(collection);
$cursor = $collection->find();
$cursor->timeout(-1);
Node.js Example:
// Database connect options
var options = { replset: { socketOptions: { connectTimeoutMS : conf.dbTimeout }}};
// Establish Database connection
var conn = mongoose.connect(conf.dbURL, options);
In PHP you could add the parameter socketTimeoutMS to the other parameters of connection string, in this case to 90 seconds.
$conn = new MongoClient("mongodb://primary:27017,secondary:27017", array("socketTimeoutMS" => "90000"));
Greetings!
Take a look at the mongodb log file and find your query in it -- how long does it take to execute? If it does take a long time, have you added indexes? Are they being used? Cut/paste the query from mongodb log file and try it from mongo shell -- and add ".explain()" at the end. It will tell you the execution plan that MongoDB is performing -- and perhaps you can attack your problem from that side. If your queries really do take longer than 30 seconds, you most likely need to address it anyway -- regardless of the driver timeout issues.
ensureIndex keys and try
MongoCursor::$timeout = 600000;
I've spotted this problem on removing 1-2kk logs records using php driver.
Basically i had to add timeout (i'm using indexes, just db is a bit huge)
$dtObject = new DateTime();
$dtObject->modify("- " . $interval);
$date = new MongoDate($dtObject->format("U"));
$filter = array('dtCreated' => array('$lt' => $date));
$num = $this->collection->count($filter);
if ($num > 0)
$this->collection->remove($filter)->timeout(-1);
return $num;
This worked for me

App hangs when executing the query in prepared statement

I am trying to select rows which are older than 7 days from current date. Database used is DB2 version 9.
Can you please tell me how exactly can I use the datetime in the query? The date table field is of type timestamp.
I am able to manually run the query without issues. However, when I am using in the prepared statement,
The app hangs when executing the query result = pselect.executeQuery(); as a result of which we need to restart db2 instance in order to clear it.
Can you please help what might be the issue? I do not see any exceptions at all. Other parts of the code works fine if I remove the select_query part.
try{
String select_query = "SELECT URL_ID ,URLVAL FROM URL_TAB WHERE " +
"UPDATED_DATE < TIMESTAMP(CURRENT_DATE - 7 DAYS, '00.00.00')";
System.out.println("select_query=" + select_query);
conn = JDBCDataObjectFactoryManager
.getConnection("JDBCConnectionFactory-SDE");
pselect = conn.prepareStatement(select_query);
System.out.println("pselect=" + pselect);
try{
System.out.println("inside try");
result = pselect.executeQuery();
System.out.println("result=" + result);
}catch(Exception e){
System.out.println("inside catch");
System.out.println("error message==============>"+e.getMessage());
}
if ((result != null) && (result.next())) {
System.out.println("3 >>>>>>>>>>>>>>>>>>>>>>>>>");
url_id = result.getInt(1);
url = result.getString(2);
}//end if
There are two possibilities: either the query is in a lock wait, or it runs for so long that it appears to be hung.
Check what is the value of LOCKWAIT database configuration parameter --by default it is -1, which means infinity, and you normally want to set it to a more reasonable value, typically 30 or 60 seconds. If it is the lock wait that causes your application to "hang", you would get an exception instead, which will help you to debug further.
If the issue is caused by the poor query performance, you'll need to work with your DBAs to figure out the root cause and resolve it.

It is possible to execute MySQLi prepared statement before the other one is closed?

Lets say I have a prepared statement. The query that it prepares doesn't matter. I fetch the result like above (I can't show actual code, as it is something I don't want to show off. Please concentrate on the problem, not the examples meaningless) and I get
Fatal error: Call to a member function bind_param() on a non-object in... error. The error caused in the called object.
<?php
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
class table2Info{
private $mysqli;
public function __construct($_mysqli){
$this->mysqli = $_mysqli;
}
public function getInfo($id)
{
$db = $this->mysqli->prepare('SELECT info FROM table2 WHERE id = ? LIMIT 1');
$db->bind_param('i',$db_id);
$db_id = $id;
$db->bind_result($info);
$db->execute();
$db->fetch();
$db->close();
return $info;
}
}
$t2I = new table2Info($mysqli);
$stmt->prepare('SELECT id FROM table1 WHERE name = ?');
$stmt->bind_param('s',$name);
$name = $_GET['name'];
$stmt->bind_result($id);
$stmt->execute();
while($stmt->fetch())
{
//This will cause the fatal-error
echo $t2I->getInfo($id);
}
$stmt->close();
?>
The question is: is there a way to do another prepared statement while another one is still open? It would simplify the code for me. I can't solve this with SQL JOIN or something like that, it must be this way. Now I collect the fetched data in an array and loop through it after $stmt->close(); but that just isn't good solution. Why should I do two loops when one is better?
From the error you're getting it appears that your statement preparation failed. mysqli::prepare returns a MySQLi_STMT object or false on failure.
Check for the return value from your statement preparation that is causing the error. If it is false you can see more details by looking at mysqli::error.

zend framework 1.11.5 is choking on search function - mysql db

ZF 1.11.5 is puking all over this search function. i've tried creating the query several different ways, sent the sql statement to my view, copied and pasted the sql statement into phpMyAdmin and successfully retrieved records using the sql that ZF is choking on. i have been getting a coupld of different errors: 1) an odd SQL error about 'ordinality' (from my Googling ... it seems this is a ZF hang up .. maybe?) and 2) Fatal error: Call to undefined method Application_Model_DbTable_Blah::query() in /blah/blah/blah.php on line blah
public function searchAction($page=1)
{
$searchForm = new Application_Model_FormIndexSearch();
$this->view->searchForm = $searchForm;
$this->view->postValid = '<p>Enter keywords to search the course listings</p>';
$searchTerm = trim( $this->_request->getPost('keywords') );
$searchDb = new Application_Model_DbTable_Ceres();
$selectSql = "SELECT * FROM listings WHERE `s_coursedesc` LIKE '%".$searchTerm."%' || `s_title` LIKE '%".$searchTerm."%'";
$selectQuery = $searchDb->query($selectSql);
$searchResults = $selectQuery->fetchAll();
}
here's my model ....
class Application_Model_DbTable_Ceres extends Zend_Db_Table_Abstract
{
protected $_name = 'listings';
function getCourse( $courseId )
{
$courseid = (int)$courseId;
$row = $this->fetchRow('id=?',$courseId);
if (!$row)
throw new Exception('That course id was not found');
return $row->toArray();
}
}
never mind the view file ... that never throws an error. on a side note: i'm seriously considering kicking ZF to the curb and using CodeIgniter instead.
looking forward to reading your thoughts. thanks ( in advance ) for your responses
You're trying to all a method called query() on Zend_Db_Table but no such method exists. Since you have built the SQL already you might find it easier to call the query on the DB adapter directly, so:
$selectSql = "SELECT * FROM listings WHERE `s_coursedesc` LIKE '%".$searchTerm."%' || `s_title` LIKE '%".$searchTerm."%'";
$searchResults = $selectQuery->getAdapter()->fetchAll($selectSql);
but note that this will give you arrays of data in the result instead of objects which you might be expecting. You also need to escape $searchTerm here since you are getting that value directly from POST data.
Alternatively, you could form the query programatically, something like:
$searchTerm = '%'.$searchTerm.'%';
$select = $selectQuery->select();
$select->where('s_coursedesc LIKE ?', $searchTerm)
->orWhere('s_title LIKE ?', $searchTerm);
$searchResults = $searchQuery->fetchAll($select);

How to block SQL injection for this query?

now i have this form post script
<?
if(isset($_POST['baslik'])) {
$sql = "INSERT INTO yazilar (baslik, spot, spot_kisa, spot_resim, spot_resim_isim, icerik, kategori, tiklanma, eklemetarihi)
VALUES
('$_POST[baslik]','$_POST[spot]','$_POST[spot_kisa]','$_POST[spot_resim]','$_POST[spot_resim_isim]','$_POST[icerik]','$_POST[kategori]','$_POST[tiklanma]','$_POST[tarih]')";
$sonuc = mysql_query($sql) or die(mysql_error());
if ($sonuc) {
echo ("<p class='msg done'>Yeni icerik basarili bir sekilde eklendi.</p>");
exit;
}
else {
$error = "<p class='msg warning'>Ekleme basarisiz oldu.</p>";
}
}
?>
how can i ignore sql injections for this query?
Use parametrised queries. Unfortunately these are not supported by the mysql extension in PHP 4, but if you are using PHP 5, you can use the mysqli extension or PDO instead, where they are.
See http://www.php.net/manual/en/mysqli.prepare.php for an example of how this is done.
Using parametrised queries as jammycackes suggests is the way to go, but if you for some reason cannot use them then you can use the mysql-real-escape-string function to block most (all?) dangerous values. The problem is that you must use it on every received value, so you cannot use the shorthand notion you use in your example.