Execute stored function with PHP PDO - php

I have this function stored on my SQL SERVER DATABASE
CREATE FUNCTION [dbo].[fn_md5] (#data VARCHAR(10), #data2 VARCHAR(10))
RETURNS BINARY(16) AS
BEGIN
DECLARE #hash BINARY(16)
EXEC master.dbo.XP_MD5_EncodeKeyVal #data, #data2, #hash OUT
RETURN #hash
END
To get value that i need i some how to execute like this: [dbo].[fn_md5]('data1','data2')
How i do this in php with pdo?
If i use
$exc_line = $db->prepare("exec [dbo].[fn_md5]('data1','data2')");
$exc_line->execute();
$exc_line_data = $exc_line->fetch();
I get no results...

To resolve an issue, lets just compile the answer.
Stored functions executing by SELECT statement. Stored procedures - by EXEC statement, according to docs.
So use this:
SELECT [dbo].[fn_md5]('data1','data2')

Related

Adodb.GetRow() not returning data when there is a Insert before a Select in the query

I'm new. Most of the times I find solutions here just by reading but now I have to ask you directly because of the weirdness of my subject.
I have an application in php and I used to use the mssql libraries to connect to MS Server 2008 but now I migrated part of my code to connect through ADODB http://adodb.sourceforge.net/
I have a store procedure which I use to validate/insert/update/delete rows depending of parameters I send, so at the very bottom I have a line of code like this
Select #Result Result
This variable just tell me everytime if the proccess went correctly or if I'm missing something so the row doesn't get inserted/deleted/updated.
Here the code of my store procedure
create procedure sp_MyTable #id int, #name varchar(100), #type varchar(10)
as
declare #Results varchar(100)
set #Result=#type
--validations!
if exists(select * from MyTable where name=#name)begin
set #Result='No insert:('
end
if #Result='insert'
insert into MyTable (name)values(#name)
select #Result Result
Here and example of code to create my connection in php
$pQry='exec sp_MyTable #id="0",#name="Hello",#type="insert"';
require ("php/ExtClases/adodb5/adodb.inc.php");
$db = ADONewConnection('mssqlnative');
$db->debug = false;
$db->Connect($datCon['sServer'], $datCon['UID'], $datCon['PWD'], $datCon['Database']);
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$rs = $db->Execute($pQry);
$rows=$rs->GetRows();
So, it is supposed to return and Array like this
print_r($rows);
//Array ([0]=>Array( [Result] => insert )) )
But It prints just nothing.
Using Management Studio I already ran this procedure directly on my own computer and at the server online and both cases retrieved data, so the store procedure is fine.
If I remove the insert statement:
create procedure sp_MyTable #id int, #name varchar(100), #type varchar(10)
as
declare #Results varchar(100)
set #Result=#type
--validations!
if exists(select * from MyTable where name=#name)begin
set #Result='No insert:('
end
/*
No insert!
*/
select #Result Result
It works!.
print_r($rows);
//Array ([0]=>Array( [Result] => insert)) )
_UPDATE: even if I print something (print 'something') in the store procedure ADODB ignores the select statement, so the select must be totally alone.
I think I will consider searching for another way.
_.
PD: Sorry for my bad english.
Regards.
Well, it took a few hours of my appreciated life but at last now I know what is going on.
MSSQL driver use to ignore all but the last statement (as I remember...). So, if you have something like this
$query="select * from table1; select some, data from table2; select yadda yadda from table3";
$conn=mysql_connect($sServer,$UID,$PWD);
$baseDatos=mysql_select_db($Database,$conn);
$res=mysql_query($query);
While($row=mssql_fetch_array($res)){
print($row);
}
You will have printed the results only of table3.
( ACTUALLY Here it is written that you can have multiple recorset and navigate through them with mssql http://www.php.net/manual/es/function.mssql-next-result.php but at the moment I don't know why it takes just the last one as the first one. Maybe it doesn't recognize prints or inserts as recorsets at all)
ADODB library actually uses SQLSRV to handle connections and queries to any sql server (mssqlnative). SQLSRV is the official driver released for Microsoft so is slightly different. You need to use the function sqlsrv_next_result or it will be return just the first result whatever it is (print,insert,select,etc)
here the link
http://www.php.net/manual/en/function.sqlsrv-next-result.php
and another guy who had the same problem
SQLSRV and multiple selects in Stored Procedure
what I did is not pretty but with patience I think I can fix it in the future, for now I just need the last recorset (table3) and not the first, so ...
/*here my temporary fix*/
do {
$result = array();
while ($row = sqlsrv_fetch_array($this->_queryID)) {
$result[] = $row;
}
} while (!is_null(sqlsrv_next_result($this->_queryID)));
return $result;
/**/
I overwrite the variable $result with every step into the results :). Funny code.
Cheers

Using SQL Server, is there a way to query (555) 344-2524 using 5553442524?

Using the PHP SQLSRV driver to connect to SQL Server 2000, is there a way I could match all of these rows using this piece of data: 5553442524?
555-344-2524
(555) 344-2524
555.344.2524
1-555-344-2524
I imagine this would be done through a specific query probably using a stored procedure?
Thank you.
For SQL 2000 the only way I can think of would be using the REPLACE function.
declare #SearchTerm bigint
Set #SearchTerm = 5553442524
Select * From dbo.Table
Where Replace(Replace(Replace(Replace(Col1,'-',''), '(',''),')',''),'.','')
= #SearchTerm
The problem with this would be it wouldn't cater for the leading 1.
A better way would be wrap all this logic in to a function.
e.g.
Create Function dbo.fn_FormatTelephoneNumber(#input varchar(100))
returns bigint
as begin
declare #temp bigint
Set #temp = Replace(Replace(Replace(Replace(#input ,'-',''), '(',''),')',''),'.','')
If Len(#temp) = 11
begin
Set #temp = Right(#temp, 10)
end
return #temp
End
To call the function you would use it like so:
Select *,
dbo.fn_FormatTelephoneNumber(YourColumnName) as [FormattedTelephoneNumber]
From dbo.YourTable
Or to use it in a WHERE clause:
Select *
From dbo.YourTable
Where dbo.fn_FormatTelephoneNumber(YourColumnName) = 5553442524
Obviously the best thing here would be to clean up the data that is stored in the columns and restrict any further "bad" data from being inserted. Although in my experience that is easier said than done.

Could you please assist me with PHP 5.3 and MySQL 5.5 stored procedures and mysqli library + persistent connection

Helo,
I have a stored procedure that has 7 IN parameters and 3 OUT parameters.
I need to pass 7 parameters IN from PHP, execute the query with procedure, and retrieve the 3 OUT parameters.
I am using mysqli with persistent connection mode enabled. (For load considerations)
What is the most efficient way to execute the query and get results?
I need something that doesn't affect other concurrently running PHP scripts, and that cleans the result itself, and that is straightforward.
This is what my application is (simplified) (not a working example, just how i wish it was)
$inParam1 = 'wer';
$inParam2 = 'fewf';
$inParam3 = 'dsf';
$inParam4 = 'vccv';
$inParam5 = '34t3';
$inParam6 = 'ter';
$inParam7 = 'ert';
$query = "CALL my_procedure('$inParam1', '$inParam2', '$inParam3', '$inParam4', '$inParam5', '$inParam6', '$inParam7', #outParam8, #outParam9, #outParam10); SELECT #outParam8, #outParam9, #outParam10;";
$result = $mysql_query($query);
list($outParam1, $outParam2, $outParam3) = mysql_fetch_array($result);
echo $outParam1; // String param #1 that my procedure returned as an OUT variable
echo $outParam2; // String param #2 that my procedure returned as an OUT variable
echo $outParam3; // String param #3 that my procedure returned as an OUT variable
If somebody could show how this code could look in reality, please please would be great!
I am obviously using mysqli with proper connection, and such, but the examples I have found in internet are really confusing and seem to be inefficient, I am also worried if it will conflict with other clients, because it works like "nextResult" and other some strange functions.
Many thanks!
PHP 5.3, MySQL 5.5
Try looking here. As im not overly familiar with this. :)
http://www.mysqltutorial.org/stored-procedures-parameters.aspx
You need to create a query first. This query will then be stored in the database as a callable procedure. Then later using whatever language you can call the procedure.
DELIMITER //
CREATE PROCEDURE GetUserByCountry(IN countryName VARCHAR(255))
BEGIN
SELECT name, email
FROM users
WHERE country = countryName;
END //
DELIMITER ;
Then calling it.
CALL GetUserByCountry('mexico')
Returns all users names and emails who live in mexico.
I believe if you want to create a dynamic query string such as yours, you need to put {} around your variables in the string.
$query = "CALL my_procedure('{$inParam1}', '{$inParam2'}, '{$inParam3}', '{$inParam4}', '{$inParam5}', '{$inParam6}', '{$inParam7}', #outParam8, #outParam9, #outParam10); SELECT #outParam8, #outParam9, #outParam10;";

PHP: calling Oracle stored proc that returns a table

I have an Oracle stored proc that takes 2 parameters. userid as an input parameter and an Oracle table with 2 columns as second out parameter. How can I invoke the procedure from PHP? I think that the problem stands in the oci_bind_* for the second parameter. I've tried oci_bind_array_by_name but I always get PLS-00306: wrong number or types of arguments in call to GET_VALUES.
Can anyone help me, please?
Here is my code:
$tab=array();
$query = "begin GET_VALUES(:P_CUSTOMERCODE,:P_TAB); end;";
$stmt = oci_parse($ora_conn, $query) or die(oci_error());
oci_bind_by_name($stmt,":P_CUSTOMERCODE",$codUtente,255);
oci_bind_array_by_name($stmt,":P_TAB",$tab,100,100,SQLT_CHR);
oci_execute($stmt) or die(oci_error());
This might answer your problem: How to call package from php having procedure in oracle using oci drivers?
Not sure a multi-column table will work with oci_bind_array_by_name. Looking at the php manual, you can use this to bind a simple varray, assoc array or nested table, basically as simply 1 column list of values. You'd specify the type of array in the "type" param, using SQLT_CHR for varchar2 for example (if you defined an array like : type t_array is table of varchar2(100) index by pls_integer).
Seems you created a custom table of a custom record type(?), something like:
type t_rec is record (
col1 number,
col2 varchar2(100)
);
type t_tab is table of t_rec;
I don't see where you can bind to t_tab as an out param using php's oci8 calls, but I may be mistaken.

Can you return multiple result sets using PDO and PostgreSQL?

I would like to group multiple queries into a single function that lives in PostgreSQL. The function will be queried using PDO.
The function is:
CREATE OR REPLACE FUNCTION "test_multipe_refcursor"()
RETURNS SETOF refcursor AS $BODY$
DECLARE
parentRC refcursor;
childRC refcursor;
BEGIN
open parentRC FOR
SELECT * FROM parent;
RETURN NEXT parentRC;
open childRC FOR
SELECT * FROM child;
RETURN NEXT childRC;
RETURN;
END;$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION "test_multipe_refcursor"() OWNER TO postgres;
Here's the PHP code. "Database" as a singleton class that sets up the usual connection properties, nothing special.
$database = Database::load();
$sql = "select * from test_multipe_refcursor();";
$p = $database->query($sql);
$i = 1;
do
{
$this->set('set' . $i, $p->fetchAll(PDO::FETCH_ASSOC));
$i++;
} while ($p->nextRowset());
$p->closeCursor();
And the result.
PDOException: SQLSTATE[IM001]: Driver does not support this function: driver does not support multiple rowsets in xxxx.php on line 32
This would seem to indicate that it's not supported, but then again, I cannot find a list defining exactly what is.
Has anyone managed to get this working?
References:
http://www.sitepoint.com/forums/showthread.php?p=3040612#post3040612
PostgreSQL function returning multiple result sets
http://ca.php.net/manual/en/pdostatement.nextrowset.php
Support for returning multiple resultsets is still on the PostgreSQL todo list and it will definitely not hit 8.4. As for the setof refcursors method, What you are trying to do doesn't work because the function isn't returning multiple rowsets - it is returning one rowset of refcursors. I'm not sure if using refcursors client side works, but I don't find it likely, even if the client-server protocol supports it, it is unlikely that PDO has an API for that.
But why are you trying to return multiple resultsets in one query? You can always do the queries separately.
Near the bottom of this PostgreSQL doc page, there is a section describing how you can pass back one or more cursors from a function. Basically, you get the caller to specify the name of the cursor(s) as parameters:
CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$
BEGIN
OPEN $1 FOR SELECT * FROM table_1;
RETURN NEXT $1;
OPEN $2 FOR SELECT * FROM table_2;
RETURN NEXT $2;
END;
$$ LANGUAGE plpgsql;
-- need to be in a transaction to use cursors.
BEGIN;
SELECT * FROM myfunc('a', 'b');
FETCH ALL FROM a;
FETCH ALL FROM b;
COMMIT;
The page is for PostgreSQL 8.4, but this documentation snippet is present at least as far back as 8.1 (the version I'm running). As the comment says, you need to be inside a transaction to use cursors, as they are implicitly closed at the end of each transaction (i.e. at the end of every statement if autocommit mode is on).

Categories