I have a Postgres database I wish to access. I need to call several functions that exist in the DB. I have achieved connection to the database and running queries. I have also achieved to call the functions I want. My problem is that when a Postgres function has more than one OUT parameters, instead of returning an array I can access either with the offset or with the row name, it instead returns a string with both the OUT parameters:
$query = "Select pg_function('" . Getenv("REMOTE_ADDR") . "')";
$result = pg_query($query);
$line = pg_fetch_array($result, NULL, PGSQL_ASSOC);
var_dump($line);
What var_dumb returns is this:
array
'ua_bl_session_request' => string '(c6787f5f2b2c885168162c8c8ffff220,8fe04393-c188-0e08-b710-a2ce89066768)' (length=71)
I can of course parse that string but is there a way to achieve what I want and I am missing it?
SELECT * FROM pg_function(REMOTE_ADDR);
Maybe you are using pg_fetch_array() incorrectly, because you should give the row number in the second parameter. For example:
// To get the first row (Rows are numbered from 0 upwards)
$line = pg_fetch_array($result, 0, PGSQL_ASSOC);
// To get the second row
$line = pg_fetch_array($result, 1, PGSQL_ASSOC);
But if you know what you are doing, you can use regexp_split_to_table(), it is a Posgtres string function that split a string to rows using a POSIX regular expression as the delimiter. For example:
$query = "select regexp_split_to_table(
pg_function('" . Getenv("REMOTE_ADDR") . "'), ','
)";
In your case, it will split the function's result using ',' as delimiter. It should return a result set with two rows, like below:
c6787f5f2b2c885168162c8c8ffff220
8fe04393-c188-0e08-b710-a2ce89066768
Related
I'm switching from pg_exec to pg_query_param and when I use a normal query everything it's ok but, I have a problem when I want to use a Postgres function on the database.
Here my actual code:
$sql = "select accsmap.prep_download_files('".$dataType."','{".
$severity."}','{".
$year."}','{".
$region."}')";
$result = pg_exec($connect,$sql);
$connect it's just the DB info to connect to it.
and Here my new code:
$result = pg_query_params($connect,"select accsmap.prep_download_files( ".
"$1" ." ,{ ". "$2" ." },{ ". "$3" ." },{ ". "$4" ." });",
array($dataType, $severity, $year, $region) );
I've tried a lot of ways to translate the $sql var into the query but always it returns me errors near , or { }
and here a sample of $sql
select accsmap.prep_download_files('for Accidents occuring in the following
Authorities','{1,2,3}','{2014,2016}','{E08000001,E06000028,E06000036}')
The function expect $severity, $year and $region as array.
The problem is the way you are handling the parameters. For example:
pg_query_params($dbconn, 'SELECT * FROM shops WHERE name = $1', array("Joe's Widgets"));
If you see the query, there is a column called name (character data type) and it should be single quoted name = 'name'. But since it is inside the pg_query_params, you just use name = $1 'cause the function escapes the parameter and adds the quotes.
Therefore, since you use a postgreSQL array, it fails in constructing the query because your parameters arent well constructed. If your variable $severity is like this $severity="1,2,3" it will try to add a escaped parameter to the reference returning something like this: {'1,2,3'}.
On the other hand, If one of the parameters is an array like in your case (array of ints being passed to a stored procedure), it must be denoted as a set within the array, not php array notation.
I can't test the code, but I believe that the correct way to do it should be:
$severity='{1,2,3}';
$year='{2014,2016}';
$region='{E08000001,E06000028,E06000036}';
$result = pg_query_params($connect,"select accsmap.prep_download_files($1, $2, $3, $4)",
array($dataType, $severity, $year, $region) );
Unless I am missing something very obvious, I would expect the values of $data1 and $data2 to be the same?? But for some reason when I run this scenario twice (its run once each function call so I'm calling the function twice) it produces different results.
Call 1: PDO = Blank, Sprintf = 3 rows returned
Call 2: PDO = 1 row, Sprintf = 4 rows (which includes the PDO row)
Can someone tell me what I'm missing or why on earth these might return different results?
$sql = "SELECT smacc.account as Smid,sappr.*,CONCAT('$domain/',filepath,new_filename) as Image
FROM `{$dp}table`.`territories` pt
JOIN `{$dp}table`.`approvals` sappr ON pt.approvalID = sappr.ID
JOIN `{$dp}table`.`sm_accounts` smacc ON pt.ID = smacc.posted_territory_id
LEFT JOIN `{$dp}table`.`uploaded_images` upimg ON pt.imageID = upimg.ID
WHERE postID = %s AND countryID = %s AND smacc.account IN (%s) AND languageID = %s";
echo sprintf($sql,$postID,$countryID,implode(',',$accs),$langID);
$qry1 = $db->prepare(str_replace('%s','?',$sql));
$qry1->execute(array($postID,$countryID,implode(',',$accs),$langID));
$data1 = $qry1->fetchAll();
print'<pre><h1>PDO</h1>';print_r($data1);print'</pre>';
$qry2 = $db->query(sprintf($sql,$postID,$countryID,implode(',',$accs),$langID));
$data2 = $qry2->fetchAll();
print'<pre><h1>Sprintf</h1>';print_r($data2);print'</pre><hr />';
The root of the problem is the implode(',',$accs) function.
While you are using sprintf() it will generate a coma separated list and that list will be injected into the query string.
The result will be something like this:
smacc.account IN (1,2,3,4,5)
When you are binding the same list with PDO, it handles it as one value (a string: '1,2,3,4,5'). The "result" will be something like this:
smacc.account IN ('1,2,3,4,5')
Note the apostrophes! -> The queries are not identical.
In short, when you are using PDO and binding parameters, you have to bind each value individually (you can not pass lists as a string).
You can generate the query based on the input array like this:
$query = ... 'IN (?' . str_repeat(', ?', count($accs)-1) . ')' ...
// or
$query = ... 'IN (' . substr(str_repeat('?,', count($accs)), 0, -1) . ')'
This will add a bindable parameter position for each input value in the array. Now you can bind the parameters individually.
$params = array_merge(array($postID, $countryID), $accs, array($langID));
$qry1->execute($params);
Yes as Kris has mentioned the issue with this is the IN part of the query. Example 5 on the following link helps fix this: http://php.net/manual/en/pdostatement.execute.php. I tried using bindParam() but that didn't seem to work so will use Example 5 instead.
In the project that I am creating, I have a mysql column that is an array of different pieces of data from the database. These pieces of data have info that I want to display. In order to separate these items in the array I used,
$get_query = mysql_query('Select array FROM data');
while($dataRow = mysql_fetch_assoc($getfrnd_query)) {
$array = $dataRow['array'];
if($array != "") {
$data_from_array_column = explode("," $array);
$getdata = mysql_query("SELECT * FROM info WHERE item = $data_from_array_column");
//Then I used a mysql_fetch_assoc to get data based on the item.
}
}
When I run this code, I get an error "Array to string conversion on the line with $getdata".
Is there any way to get this to work?
Thank you.
The problem is that explode returns an array containing the strings in between the character(s) you used as a delimiter (, in your case), not a string.
PHP is getting mad because it doesn't know how to convert your array to a string automatically. So, you will need to convert it yourself. The options are:
You want to select the row where item is equal to the nth element in the array, $data_from_array_column. If this is the case, you need to insert the following line of code after your explode:
$data_from_array_column = $data_from_array_column[0];
If you want to select where it matches any of the elements in the $data_from_array_column array, it will get more complicated. You would need to add this line after the explode:
$data_from_array_column = implode("' OR item='",$data_from_array_column);
and change your query on the next line to:
$getdata = mysql_query("SELECT * FROM info WHERE item='$data_from_array_column'");
This will create a MySQL query that looks some thing like this:
SELECT * FROM info WHERE item='foo' OR item='bar' OR item='bla'
For an application I'm trying to count the total of friends. I want to do this with a function but it isn't returning anything. It tells me this:
Warning: mysqli_query() expects at least 2 parameters, 1 given
But I only need one parameter. I think I'm totally wrong.
This is the function:
public function GetTotalOfFriends($user_id){
$db = new Db();
$select = "SELECT COUNT FROM friendship WHERE (friendship_recipient_id ='" . $user_id ."' OR friendship_applicant_id = '" . $user_id . "') AND friendship_status = 'accepted'";
$result = $db->conn->query($select);
$row = mysqli_query($result);
$total = $row[0];
echo $total;
I'm trying to print it out in this way:
$friend = new Friendship;
$numberoffriends = $friend->GetTotalOfFriends($user_id);
<?php echo $numberoffriends; ?>
You are mixing up a couple of things. The line $result = $db->conn->query($select); already seems to execute a query, but then you try to bypass your database wrapper by passing that query result again to mysqli_query.
Apart from that, I think your query itself is also wrong. COUNT needs a parameter, indicating a field or value to count. Quite often COUNT(*) is used, but COUNT('x') might be more efficient in some cases. You can also use a specific field name, and COUNT will count the non-null values for you.
The result you got is a mysql_result object, which you need to use to get to the actual data of the query result.
The documentation of this object is here and I suggest that you read it thoroughly.
One possible way to do this is using this:
$resultArray = $result->fetch_row();
This will result in the first (and only) row of your query. It is represented as an array, with one value (since your query returns only one column). You can fetch that value like this:
return $resultArray[0];
You could also use any of the other fetch methods if you want your data in a different fashion.
php and mysql...
the query:
$sql = "SELECT keyterm
FROM keyterms
WHERE keyterm_id = $keyterm_id";
$result = mysqli_query($dbcon,$sql); // returns a single result
fetch results:
$keyterm = mysqli_fetch_assoc($result);
$keyterm = $keyterm["keyterm"];
what is the equivalent of the last two lines in a single line?
You need to use fetch_object() because PHP allows you to chain the ->operator directly onto the return value of a function, which you cannot do with the [ ] operator.
$keyterm = $result->fetch_object()->keyterm;
Or, procedural style:
$keyterm = mysqli_fetch_object($result)->keyterm;
extract() (take care):
extract(mysqli_fetch_assoc($result));
You will get a warning when mysqli_fetch_assoc() returns FALSE (non-array). Field/Column name must be named as the variable.
Edit: Made it bold as some might have not read that.
If you only fetch a single column, you can also use:
$keyterm = current(mysql_fetch_array($result));
Works since PHP5. It just gets the first entry from the array (whether indexed or associative), and assigns it to the variable. That's the cheapest option here.