Execute Oracle stored procedures with Symfony & doctrine - php

I am trying to execute an stored procedures inside an Oracle database :
x_pkg.get_xID
It require one input & will output a single string
I already tried several different options that I found in internet :
$val = 'DATABASE';
$result = new ResultSetMapping ();
$query = $entityManager -> createNativeQuery ("BEGIN x_pkg.get_xID(${val}, :cursor); END;", $result);
In this case I get error : ORA-01008: not all variables bound (500 Internal Server Error)
$query = $entityManager -> createNativeQuery ("CALL x_pkg.get_xID(:data)", $result);
$query -> setParameters (['data' => $val]);
In this case I get error : ORA-06553: PLS-306: wrong number or types of arguments in call to 'GET_XID' (500 Internal Server Error)
$query = $entityManager -> createNativeQuery ("CALL x_pkg.get_xID(${val})", $result);
In this case I get error : ORA-06576: not a valid function or procedure name (500 Internal Server Error)
Thank you for your help.

I can help you explain why you get these errors and then it might help you to find the solution to solve the problem,
And just keep it in mind, the Oracle database is a bit tricky and different than other community used database such as MySQL, it has it's own power and strict rules,
**I will explain the first case at the end.*
So, in your second case, you get that error because Oracle expect the OUT variable to be a part of your Call which is not the case in your code and because it is inside the procedure
In your third case, using ${val} is not valid even if it's valid for PHP itself, the Oracle database see it in other way, so this is not an option for you,
Now about the first case, you should make sure that your procedure is returning a cursor and not a variable, I think you should check it in your Oracle database and also in your next line of code where you execute your query (it's not posted here so I can't be sure about it), this is a tricky part of Oracle database, you should make sure what your procedure is returning to avoid the error,
And good luck :)

Related

Why are all of my images getting cut off when I pull the binary out of a SQL Server DB?

I'm using PDO in PHP 7 on an Amazon Linux AMI to connect to a SQL Server DB running on Amazon RDS.
Thus far, I've been able to extract all of the data out of the DB just fine except for one column in one table. The column is of the type image and contains binary data.
When I attempt to use PDO in PHP to select from the column in question and then output the binary to the browser window with the necessary header sent (e.g., header('Content-Type: image/jpeg');), I can only see a part of the file (in the case of an image) or I get a corrupt-file error (in the case of a PDF).
In a few edge cases (I'm presuming when the file size is quite small), I can see the full image, but that's rare.
The following is an example of this problem in Chrome:
I've done some pretty extensive Googling on this issue, but there doesn't seem to be a lot of info on this issue, and all the pages I've seen are quite old and related to either mssql (no longer available in PHP 7) or sqlsrv drivers.
Here are some examples of (seemingly) related pages I've found:
https://www.reddit.com/r/PHP/comments/m6v1t/need_help_displaying_jpg_from_mssql_image_field/
https://css-tricks.com/forums/topic/blob-display-is-truncated/
PHP is truncating MSSQL Blob data (4096b), even after setting INI values. Am I missing one?
Does anyone have any ideas as to why this is happening and how I can fix it? I feel like PDO should be able to handle this, but if there is an issue with PDO and I need to use some other drivers to handle this, that's fine too.
Thank you.
I finally found the answer. The data coming back to PHP via PDO was in fact being truncated at 64k, thus causing issues.
Alex helped lead me on the right path by suggesting setting TEXTSIZE to -1. The rookie mistake that I made was that I did SET TEXTSIZE -1 from Microsoft SSMS, assuming that it would be set globally for all connections, which was not the case. It only set it for the SSMS connection, thus the problem.
However, when I finally did the following in PDO in PHP, that is, set TEXTSIZE to -1 with the PDO connection and then make the query from PDO, I was able to set TEXTSIZE for the PDO connection and then get back all the data:
doSqlServerQuery("SET TEXTSIZE -1;");
$results = doSqlServerQuery("SELECT binary-data-image-column AS data
FROM table-name
WHERE key = 95948578934578934;");
//Function definition
function doSqlServerQuery($query, $dbh = null) {
if (!isset($dbh)) {
global $dbh;
}
$stmt = $dbh->prepare($query);
if ($stmt) {
$stmt->execute();
$results = [];
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
$results[] = $result;
}
return $results;
} else {
pO($dbh->errorInfo());
}
}
Just fixed this myself, it is being cut off after 64KB has been uploaded, to fix this, either set a limit at 64KB or change it to a longblob, which gives you 4 gigabytes of storage instead of 64 kilobytes.

SQLSRV with Linked Server

My issues basically revolves around me needing/preferring to use PHP's sqlsrv to access a sql-server 2000 database. I've worked on the project already using that with a sql server 2005 to run all the queries through and switching to something like the ODBC PHP drivers would be a pretty big headache right now. So now I have the original SQL Server 2000 database and 2005 installed on the same computer and I've created a linked server between the 2. Testing it out in Management Studio Express worked by running a simple query to one of the tables.
Now, I'm using the exact same query in PHP using sqlsrv_query and running into an error. My PHP code to test this out looks like this
$connectionOptions = array("UID"=>"user","PWD"=>"password");
$res = sqlsrv_connect("(local)\SQLExpress", $connectionOptions);
if(!$res) die("ERRORS : " . print_r(sqlsrv_errors()));
echo "SELECT * FROM [ServerName].DB.dbo.Table<br/>";
$res = sqlsrv_query($res,"SELECT * FROM [ServerName].DB.dbo.Table");
if($res===false){
die("ERRORS : " . print_r(sqlsrv_errors()));
}else{
var_dump($res);
$ary = sqlsrv_fetch_array($res);
}
var_dump($ary);
echo "<hr>";
var_dump(sqlsrv_errors());
The problem with this code is that the result of of sqlsrv_query doesn't return false but returns resource(11) of type unknown. So running fetch_array on that result tells me that an invalid parameter was passed to sqlsrv_fetch_array. I'm not sure what to do at this point. Is there just a problem running a query on a linked server through sqlsrv?
seems no error in your code.
Please try the fetch_array in a loop and update the result.
while($row = sqlsrv_fetch_array($result))
{
echo($row['field_name']);
}
also remove var_dump($ary);
Usually even if there is any error in the data display using '$row', the error message will show problem with 'sqlsrv_fetch_array'.
Well I figured out the problem. In my haste to make some code to test out whether or not the linked server worked, I just used the same variable name for the result of sqlsrv_connect and sqlsrv_query. Turns out, that was the whole problem. I switched the variable names so that the connection object is $Link and the query stays as $res. Now, I get the access to the database that I was trying to get through 2005 into 2000. So in the future, I definitely will name my variables a bit more carefully so I don't bang my head against the wall for hours.

PHP calling PostgreSQL function - type issue?

I have a function in PostgreSQL / plpgsql with the following signature:
CREATE OR REPLACE FUNCTION user_login(TEXT, TEXT) RETURNS SETOF _get_session AS $$ ... $$
Where _get_session is a view. The function works fine when calling it from phpPgAdmin, however whan I call it from PHP I get the following error:
Warning: pg_query() [function.pg-query]: Query failed: ERROR: type
"session_ids" does not exist CONTEXT: compile of PL/pgSQL function
"user_login" near line 2 in /home/sites/blah.com/index.php on line 69
The DECLARE section of the function contains the following variables:
oldSessionId session_ids := $1;
newSessionId session_ids := $2;
The domain session_ids DOES exist, and other functions which use the same domain work when called from the same script. The PHP is as follows:
$query = "SELECT * FROM $dbschema.user_login('$session_old'::TEXT, '$session'::TEXT)";
$result = pg_query($login, $query);
I have also tried this using ::session_ids in place of ::TEXT when calling the function, however I recieve the same error.
Help :o(
Just make your code simple:
$query = "SELECT * FROM $dbschema.user_login($1, $2)";
$result = pg_query_params($login, $query, array($session_old, $session));
Now you're safe from SQL injection.
But, your function is still wrong, there is no datatype "session_ids". I think you want to use TEXT in the DECLARE part.
If your query covers multiple lines, then PHP is most likely not sending them as part of the same transaction. If this is the case you have two options.
The first option is to send all the queries in the same call
pg_query("query1; query2; query3;");
The second option (and the best in my opinion) is to use transactions. This will allow you to make the calls over several lines though the begin statement will most likely need to be sent with the initial query.
pg_query("begin; query1;");
pg_query("query2;");
pg_query("commit;");
If there is an error that occurs, then replace the commit with a rollback, and no changes will have been made to the db.
When working with Postgres, this is actually a good rule of thumb to follow anyway.

mysqli->prepare function returns null

This is a terrible question because I don't have a simple way to reproduce it. However, I'm using the Zend Framework to connect to my MySQL database on OS X. Sometimes a call to the prepare function on a mysqli object returns null. The stated return values for the prepare function are false or a statement object.
I can't figure out where else to look for info on why the prepare statement is failing. Is there any way to get visibility into the prepare process to see why it is failing? All of my problems are coming up while a transaction is open.
Sorry for the lack of specifics, but I really can't nail down why this is happening.
Just to correct ToughPal, you should be using:
mysqli_query($db, "INSERT INTO table (variable1, variable2) VALUES (hello, mynameis);
Remember that you need to have the db connection defined and stated in the query first, before your actual SQL.
Remember to enclose the table name, column names and value data in backtick escapes.
Example prepared statement
$result = $db->query( 'INSERT INTO server (key, value) VALUES (:key, :value)',
array('key' => $foo, 'value' => $bar)
Can you let us know your DB query?
Try and execute your DB query with test data and see if the query works fine to start with. If the query is ok then we can look why the code fails.
Well I managed to find the issue over the weekend but was really only able to fix the symptoms and not the cause.
I didn't include any SQL in the original issue because the problem was happening randomly, the same code would sometimes work and sometimes not. The issue looks like it was a memory pointer problem. Whenever I had a problem Zend Debugger told me that I had a mysqli object. I believe this because otherwise I would've gotten an error when trying to run the prepare function on it. I have a singleton object that acts as a container for my mysqli connection but whenever the prepare function failed, === showed that the mysqli being used was not the same as the mysqli connection in my singleton object.
In the end, Zend Framework's only issue is that it doesn't fail if the the prepare function returns null. If you are seeing this problem use === to verify that the connection is actually the same as the one that you've previously initiated.
if you're doing something like this
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$query = "...";
$mysqli->prepare($query);
then you can inspect mysqli::$error next to see useful errors about why prepare() failed
print_r($mysqli->error);

Can PHP's SQL Server driver return SQL return codes?

Stored procs in SQL Server sometimes finish with a return code, as opposed to a recordset of data. I've seen ASP code that's able to get this return code, but I can't figure out how to get this code with PHP's mssql driver.
mssql_get_last_message() always returns nothing, and I'm thinking it's because it only returns the very last line that came from the server. When we run the proc in another application (outside PHP), there is blank line following the return code.
Has anyone figured out how to get return codes from SQL stored procs using PHP's mssql driver?
Are you talking about SQL Server error codes, e.g. RAISERRROR or other failures? If so, last time I checked in PHP you need to ask for ##ERROR (e.g. select ##error) instead.
If it is a return code, you must explicitly catch it, e.g.
DECLARE #return_code INT
EXEC #return_code = your_stored_procedure 1123
SELECT #return_code
To get a numeric error code from mssql you can do a select that looks something like
SELECT ##ERROR AS ErrorCode
Which SHOULD return the correct error code.

Categories